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 );
 }