From 0f4068ac6fa29276e637aa9a169a475eb8cfe835 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Mon, 23 Nov 2009 16:03:37 +0100 Subject: [PATCH] server: Use the file descriptor instead of the file object where possible in memory mappings. --- server/mapping.c | 67 +++++++++++++----------------------------------- 1 file changed, 18 insertions(+), 49 deletions(-) diff --git a/server/mapping.c b/server/mapping.c index 2c4bc43a8e5..67760c927d2 100644 --- a/server/mapping.c +++ b/server/mapping.c @@ -128,14 +128,11 @@ static void init_page_size(void) /* extend a file beyond the current end of file */ -static int extend_file( struct file *file, file_pos_t new_size ) +static int grow_file( int unix_fd, file_pos_t new_size ) { static const char zero; - 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 ); @@ -152,30 +149,13 @@ static int extend_file( struct file *file, file_pos_t new_size ) return 0; } -/* try to grow the file to the specified size */ -static 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(); - return 0; - } - if (st.st_size >= size) return 1; /* already large enough */ - return extend_file( file, size ); -} - /* find the shared PE mapping for a given mapping */ static struct file *get_shared_file( struct mapping *mapping ) { struct mapping *ptr; LIST_FOR_EACH_ENTRY( ptr, &shared_list, struct mapping, shared_entry ) - if (is_same_file( ptr->file, mapping->file )) + if (is_same_file_fd( ptr->fd, mapping->fd )) return (struct file *)grab_object( ptr->shared_file ); return NULL; } @@ -301,8 +281,8 @@ static int build_shared_mapping( struct mapping *mapping, int fd, /* create a temp file for the mapping */ if (!(mapping->shared_file = create_temp_file( FILE_GENERIC_READ|FILE_GENERIC_WRITE ))) return 0; - if (!grow_file( mapping->shared_file, total_size )) goto error; if ((shared_fd = get_file_unix_fd( mapping->shared_file )) == -1) goto error; + if (!grow_file( shared_fd, total_size )) goto error; if (!(buffer = malloc( max_size ))) goto error; @@ -343,7 +323,7 @@ static int build_shared_mapping( struct mapping *mapping, int fd, } /* retrieve the mapping parameters for an executable (PE) image */ -static int get_image_params( struct mapping *mapping ) +static int get_image_params( struct mapping *mapping, int unix_fd ) { IMAGE_DOS_HEADER dos; IMAGE_SECTION_HEADER *sec = NULL; @@ -357,14 +337,11 @@ static int get_image_params( struct mapping *mapping ) IMAGE_OPTIONAL_HEADER64 hdr64; } opt; } nt; - struct fd *fd; off_t pos; - int unix_fd, size; + int size; /* load the headers */ - if (!(fd = mapping_get_fd( &mapping->obj ))) return 0; - 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; @@ -406,33 +383,22 @@ static int get_image_params( struct mapping *mapping ) mapping->protect = VPROT_IMAGE; free( sec ); - release_object( fd ); return 1; error: free( sec ); - release_object( fd ); set_error( STATUS_INVALID_FILE_FOR_SECTION ); return 0; } -/* get the size of the unix file associated with the mapping */ -static inline int get_file_size( struct file *file, mem_size_t *size ) -{ - struct stat st; - int unix_fd = get_file_unix_fd( file ); - - if (unix_fd == -1 || fstat( unix_fd, &st ) == -1) return 0; - *size = st.st_size; - return 1; -} - static struct object *create_mapping( struct directory *root, const struct unicode_str *name, unsigned int attr, mem_size_t size, int protect, obj_handle_t handle, const struct security_descriptor *sd ) { struct mapping *mapping; int access = 0; + int unix_fd; + struct stat st; if (!page_mask) init_page_size(); @@ -464,24 +430,26 @@ static struct object *create_mapping( struct directory *root, const struct unico } if (!(mapping->file = get_file_obj( current->process, handle, access ))) goto error; mapping->fd = get_obj_fd( (struct object *)mapping->file ); + if ((unix_fd = get_unix_fd( mapping->fd )) == -1) goto error; if (protect & VPROT_IMAGE) { - if (!get_image_params( mapping )) goto error; + if (!get_image_params( mapping, unix_fd )) goto error; return &mapping->obj; } + if (fstat( unix_fd, &st ) == -1) + { + file_set_error(); + goto error; + } if (!size) { - if (!get_file_size( mapping->file, &size )) goto error; - if (!size) + if (!(size = st.st_size)) { set_error( STATUS_MAPPED_FILE_SIZE_ZERO ); goto error; } } - else - { - if (!grow_file( mapping->file, size )) goto error; - } + else if (st.st_size < size && !grow_file( unix_fd, size )) goto error; } else /* Anonymous mapping (no associated file) */ { @@ -498,7 +466,8 @@ static struct object *create_mapping( struct directory *root, const struct unico } if (!(mapping->file = create_temp_file( access ))) goto error; mapping->fd = get_obj_fd( (struct object *)mapping->file ); - if (!grow_file( mapping->file, size )) goto error; + if ((unix_fd = get_unix_fd( mapping->fd )) == -1) goto error; + if (!grow_file( unix_fd, size )) goto error; } mapping->size = (size + page_mask) & ~((mem_size_t)page_mask); mapping->protect = protect;