server: Change the removable fd flag to a cacheable flag to make it possible for fd users to set it dynamically.
diff --git a/server/fd.c b/server/fd.c index ca317c4..9111a65 100644 --- a/server/fd.c +++ b/server/fd.c
@@ -197,6 +197,7 @@ char *unix_name; /* unix file name */ int unix_fd; /* unix file descriptor */ unsigned int no_fd_status;/* status to return when unix_fd is -1 */ + unsigned int cacheable :1;/* can the fd be cached on the client side? */ unsigned int signaled :1; /* is the fd signaled? */ unsigned int fs_locks :1; /* can we use filesystem locks for this fd? */ int poll_index; /* index of fd in poll array */ @@ -1546,6 +1547,7 @@ fd->sharing = 0; fd->unix_fd = -1; fd->unix_name = NULL; + fd->cacheable = 0; fd->signaled = 1; fd->fs_locks = 1; fd->poll_index = -1; @@ -1580,6 +1582,7 @@ fd->sharing = 0; fd->unix_name = NULL; fd->unix_fd = -1; + fd->cacheable = 0; fd->signaled = 0; fd->fs_locks = 0; fd->poll_index = -1; @@ -1608,6 +1611,7 @@ fd->options = options; fd->sharing = sharing; fd->unix_fd = -1; + fd->cacheable = orig->cacheable; fd->signaled = 0; fd->fs_locks = 0; fd->poll_index = -1; @@ -1823,6 +1827,7 @@ } fd->inode = inode; fd->closed = closed_fd; + fd->cacheable = !inode->device->removable; list_add_head( &inode->open, &fd->inode_entry ); /* check directory options */ @@ -1869,6 +1874,7 @@ goto error; } free( closed_fd ); + fd->cacheable = 1; } return fd; @@ -1922,6 +1928,12 @@ return fd1->inode == fd2->inode; } +/* allow the fd to be cached (can't be reset once set) */ +void allow_fd_caching( struct fd *fd ) +{ + fd->cacheable = 1; +} + /* check if fd is on a removable device */ int is_fd_removable( struct fd *fd ) { @@ -2269,7 +2281,7 @@ if (unix_fd != -1) { reply->type = fd->fd_ops->get_fd_type( fd ); - reply->removable = is_fd_removable(fd); + reply->cacheable = fd->cacheable; reply->options = fd->options; reply->access = get_handle_access( current->process, req->handle ); send_client_fd( current->process, unix_fd, req->handle );
diff --git a/server/file.c b/server/file.c index 105c339..d17b25b 100644 --- a/server/file.c +++ b/server/file.c
@@ -136,6 +136,7 @@ release_object( file ); return NULL; } + allow_fd_caching( file->fd ); } return file; }
diff --git a/server/file.h b/server/file.h index 9a348bf..26290a3 100644 --- a/server/file.h +++ b/server/file.h
@@ -71,6 +71,7 @@ extern void set_fd_events( struct fd *fd, int events ); extern obj_handle_t lock_fd( struct fd *fd, file_pos_t offset, file_pos_t count, int shared, int wait ); extern void unlock_fd( struct fd *fd, file_pos_t offset, file_pos_t count ); +extern void allow_fd_caching( struct fd *fd ); extern void set_fd_signaled( struct fd *fd, int signaled ); extern int is_fd_signaled( struct fd *fd );
diff --git a/server/mailslot.c b/server/mailslot.c index 97da8d2..051f0ad 100644 --- a/server/mailslot.c +++ b/server/mailslot.c
@@ -297,6 +297,7 @@ release_object( writer ); return NULL; } + allow_fd_caching( writer->fd ); return &writer->obj; } @@ -442,9 +443,12 @@ fcntl( fds[1], F_SETFL, O_NONBLOCK ); shutdown( fds[0], SHUT_RD ); mailslot->write_fd = fds[0]; - mailslot->fd = create_anonymous_fd( &mailslot_fd_ops, fds[1], &mailslot->obj, - FILE_SYNCHRONOUS_IO_NONALERT ); - if (mailslot->fd) return mailslot; + if ((mailslot->fd = create_anonymous_fd( &mailslot_fd_ops, fds[1], &mailslot->obj, + FILE_SYNCHRONOUS_IO_NONALERT ))) + { + allow_fd_caching( mailslot->fd ); + return mailslot; + } } else file_set_error();
diff --git a/server/mapping.c b/server/mapping.c index 1cf53b9..c8b8edf 100644 --- a/server/mapping.c +++ b/server/mapping.c
@@ -515,6 +515,7 @@ if ((unix_fd = create_temp_file( size )) == -1) goto error; if (!(mapping->fd = create_anonymous_fd( &mapping_fd_ops, unix_fd, &mapping->obj, FILE_SYNCHRONOUS_IO_NONALERT ))) goto error; + allow_fd_caching( mapping->fd ); } mapping->size = (size + page_mask) & ~((mem_size_t)page_mask); mapping->protect = protect;
diff --git a/server/named_pipe.c b/server/named_pipe.c index 95f06b9..29d5c5e 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c
@@ -838,6 +838,8 @@ server->fd = create_anonymous_fd( &pipe_server_fd_ops, fds[0], &server->obj, server->options ); if (client->fd && server->fd) { + allow_fd_caching( client->fd ); + allow_fd_caching( server->fd ); fd_copy_completion( server->ioctl_fd, server->fd ); if (server->state == ps_wait_open) fd_async_wake_up( server->ioctl_fd, ASYNC_TYPE_WAIT, STATUS_SUCCESS );
diff --git a/server/protocol.def b/server/protocol.def index e41cd18..5f1a8f9 100644 --- a/server/protocol.def +++ b/server/protocol.def
@@ -1018,7 +1018,7 @@ obj_handle_t handle; /* handle to the file */ @REPLY int type; /* file type (see below) */ - int removable; /* is file removable? */ + int cacheable; /* can fd be cached in the client? */ unsigned int access; /* file access rights */ unsigned int options; /* file open options */ @END
diff --git a/server/request.h b/server/request.h index 722fc25..7897673 100644 --- a/server/request.h +++ b/server/request.h
@@ -888,7 +888,7 @@ C_ASSERT( FIELD_OFFSET(struct get_handle_fd_request, handle) == 12 ); C_ASSERT( sizeof(struct get_handle_fd_request) == 16 ); C_ASSERT( FIELD_OFFSET(struct get_handle_fd_reply, type) == 8 ); -C_ASSERT( FIELD_OFFSET(struct get_handle_fd_reply, removable) == 12 ); +C_ASSERT( FIELD_OFFSET(struct get_handle_fd_reply, cacheable) == 12 ); C_ASSERT( FIELD_OFFSET(struct get_handle_fd_reply, access) == 16 ); C_ASSERT( FIELD_OFFSET(struct get_handle_fd_reply, options) == 20 ); C_ASSERT( sizeof(struct get_handle_fd_reply) == 24 );
diff --git a/server/sock.c b/server/sock.c index 24ad50c..639421d 100644 --- a/server/sock.c +++ b/server/sock.c
@@ -646,6 +646,7 @@ release_object( sock ); return NULL; } + allow_fd_caching( sock->fd ); sock_reselect( sock ); clear_error(); return &sock->obj; @@ -718,6 +719,7 @@ release_object( sock ); return NULL; } + allow_fd_caching( acceptsock->fd ); } clear_error(); sock->pmask &= ~FD_ACCEPT;
diff --git a/server/trace.c b/server/trace.c index fd2318e..944d939 100644 --- a/server/trace.c +++ b/server/trace.c
@@ -1475,7 +1475,7 @@ static void dump_get_handle_fd_reply( const struct get_handle_fd_reply *req ) { fprintf( stderr, " type=%d", req->type ); - fprintf( stderr, ", removable=%d", req->removable ); + fprintf( stderr, ", cacheable=%d", req->cacheable ); fprintf( stderr, ", access=%08x", req->access ); fprintf( stderr, ", options=%08x", req->options ); }