===== ChangeSet 1.1371.750.17 vs 1.1371.750.18 ===== --- 1.1371.750.17/ChangeSet 2004-04-21 08:14:20 +02:00 +++ 1.1371.750.18/ChangeSet 2004-04-21 09:47:47 +02:00 @@ -1,9 +1,9 @@ +hch@dhcp212.munich.sgi.com|fs/xfs/pagebuf/page_buf.c|20020911181210|29475|cad79a273705caa2 nathans@sgi.com|fs/xfs/linux/xfs_buf.c|20040421074725|10639 +hch@dhcp212.munich.sgi.com|fs/xfs/pagebuf/page_buf.h|20020911181210|62023|a708960bf9d686dc nathans@sgi.com|fs/xfs/linux/xfs_buf.h|20040421074725|62682 hch@dhcp212.munich.sgi.com|fs/xfs/linux/xfs_linux.h|20020911181206|04059|7b5ea161a7eaa95a nathans@sgi.com|fs/xfs/linux/xfs_linux.h|20040421061358|02774 hch@dhcp212.munich.sgi.com|fs/xfs/xfs_vnodeops.c|20020911181256|62846|cf2d6abea6784bb9 nathans@sgi.com|fs/xfs/xfs_vnodeops.c|20040421061358|43137 hch@dhcp212.munich.sgi.com|fs/xfs/xfs_dir2_node.c|20020911181232|26563|e5d2a2a5c9db1858 cattelan@sgi.com|fs/xfs/xfs_dir2_node.c|20040421060816|02991 hch@dhcp212.munich.sgi.com|fs/xfs/linux/xfs_globals.c|20020911181204|43692|eb5ee6f736a789a8 nathans@sgi.com|fs/xfs/linux/xfs_globals.c|20040421060327|58860 -hch@dhcp212.munich.sgi.com|fs/xfs/pagebuf/page_buf.c|20020911181210|29475|cad79a273705caa2 nathans@sgi.com|fs/xfs/linux/xfs_buf.c|20040421051240|06709 -hch@dhcp212.munich.sgi.com|fs/xfs/pagebuf/page_buf.h|20020911181210|62023|a708960bf9d686dc nathans@sgi.com|fs/xfs/linux/xfs_buf.h|20040421051241|07819 hch@dhcp212.munich.sgi.com|fs/xfs/linux/xfs_super.c|20020911181207|00374|bec0c19323e55230 nathans@sgi.com|fs/xfs/linux/xfs_super.c|20040421050125|32179 lord@sgi.com|fs/xfs/linux/xfs_iomap.c|20021106201658|64077|7a7e03287a655155 jpk@sgi.com|fs/xfs/xfs_iomap.c|20040421044803|44994 hch@dhcp212.munich.sgi.com|fs/xfs/xfs_acl.c|20020911181218|11441|5355affe396fe6fa nathans@sgi.com|fs/xfs/xfs_acl.c|20040421043330|65102 ===== fs/xfs/linux-2.6/xfs_buf.c 1.107 vs 1.108 ===== --- 1.107/fs/xfs/linux/xfs_buf.c 2004-04-21 07:12:40 +02:00 +++ 1.108/fs/xfs/linux/xfs_buf.c 2004-04-21 09:47:25 +02:00 @@ -165,8 +165,6 @@ * Mapping of multi-page buffers into contiguous virtual space */ -STATIC void *pagebuf_mapout_locked(xfs_buf_t *); - typedef struct a_list { void *vm_addr; struct a_list *next; @@ -288,67 +286,53 @@ } /* - * Walk a pagebuf releasing all the pages contained within it. + * Frees pb_pages if it was malloced. */ -STATIC inline void -_pagebuf_freepages( - xfs_buf_t *pb) +STATIC void +_pagebuf_free_pages( + xfs_buf_t *bp) { - int buf_index; - - for (buf_index = 0; buf_index < pb->pb_page_count; buf_index++) { - struct page *page = pb->pb_pages[buf_index]; - - if (page) { - pb->pb_pages[buf_index] = NULL; - page_cache_release(page); - } + if (bp->pb_pages != bp->pb_page_array) { + kmem_free(bp->pb_pages, + bp->pb_page_count * sizeof(struct page *)); } } /* - * pagebuf_free + * Releases the specified buffer. * - * pagebuf_free releases the specified buffer. The modification - * state of any associated pages is left unchanged. + * The modification state of any associated pages is left unchanged. + * The buffer most not be on any hash - use pagebuf_rele instead for + * hashed and refcounted buffers */ void pagebuf_free( - xfs_buf_t *pb) + xfs_buf_t *bp) { - PB_TRACE(pb, "free", 0); - - ASSERT(list_empty(&pb->pb_hash_list)); - - /* release any virtual mapping */ ; - if (pb->pb_flags & _PBF_ADDR_ALLOCATED) { - void *vaddr = pagebuf_mapout_locked(pb); - if (vaddr) { - free_address(vaddr); - } - } + PB_TRACE(bp, "free", 0); - if (pb->pb_flags & _PBF_MEM_ALLOCATED) { - if (pb->pb_pages) { - if (pb->pb_flags & _PBF_MEM_SLAB) { - /* - * XXX: bp->pb_count_desired might be incorrect - * (see pagebuf_associate_memory for details), - * but fortunately the Linux version of - * kmem_free ignores the len argument.. - */ - kmem_free(pb->pb_addr, pb->pb_count_desired); - } else { - _pagebuf_freepages(pb); - } - if (pb->pb_pages != pb->pb_page_array) - kfree(pb->pb_pages); - pb->pb_pages = NULL; - } - pb->pb_flags &= ~(_PBF_MEM_ALLOCATED|_PBF_MEM_SLAB); + ASSERT(list_empty(&bp->pb_hash_list)); + + if (bp->pb_flags & _PBF_PAGE_CACHE) { + uint i; + + if ((bp->pb_flags & PBF_MAPPED) && (bp->pb_page_count > 1)) + free_address(bp->pb_addr - bp->pb_offset); + + for (i = 0; i < bp->pb_page_count; i++) + page_cache_release(bp->pb_pages[i]); + _pagebuf_free_pages(bp); + } else if (bp->pb_flags & _PBF_KMEM_ALLOC) { + /* + * XXX(hch): bp->pb_count_desired might be incorrect (see + * pagebuf_associate_memory for details), but fortunately + * the Linux version of kmem_free ignores the len argument.. + */ + kmem_free(bp->pb_addr, bp->pb_count_desired); + _pagebuf_free_pages(bp); } - pagebuf_deallocate(pb); + pagebuf_deallocate(bp); } /* @@ -443,7 +427,7 @@ unlock_page(bp->pb_pages[i]); } - bp->pb_flags |= (_PBF_PAGECACHE|_PBF_MEM_ALLOCATED); + bp->pb_flags |= _PBF_PAGE_CACHE; if (page_count) { /* if we have any uptodate pages, mark that in the buffer */ @@ -478,7 +462,7 @@ if (unlikely(bp->pb_addr == NULL)) return -ENOMEM; bp->pb_addr += bp->pb_offset; - bp->pb_flags |= PBF_MAPPED | _PBF_ADDR_ALLOCATED; + bp->pb_flags |= PBF_MAPPED; } return 0; @@ -584,10 +568,7 @@ } if (pb->pb_flags & PBF_STALE) - pb->pb_flags &= PBF_MAPPED | \ - _PBF_ADDR_ALLOCATED | \ - _PBF_MEM_ALLOCATED | \ - _PBF_MEM_SLAB; + pb->pb_flags &= PBF_MAPPED; PB_TRACE(pb, "got_lock", 0); XFS_STATS_INC(pb_get_locked); return (pb); @@ -789,9 +770,9 @@ page_count++; /* Free any previous set of page pointers */ - if (pb->pb_pages && (pb->pb_pages != pb->pb_page_array)) { - kfree(pb->pb_pages); - } + if (pb->pb_pages) + _pagebuf_free_pages(pb); + pb->pb_pages = NULL; pb->pb_addr = mem; @@ -856,7 +837,7 @@ error = pagebuf_associate_memory(bp, data, len); if (error) goto fail_free_mem; - bp->pb_flags |= (_PBF_MEM_ALLOCATED | _PBF_MEM_SLAB); + bp->pb_flags |= _PBF_KMEM_ALLOC; pagebuf_unlock(bp); @@ -1189,9 +1170,9 @@ } pb->pb_flags &= ~(PBF_READ | PBF_WRITE | PBF_ASYNC | PBF_DELWRI | \ - PBF_READ_AHEAD | PBF_RUN_QUEUES); + PBF_READ_AHEAD | _PBF_RUN_QUEUES); pb->pb_flags |= flags & (PBF_READ | PBF_WRITE | PBF_ASYNC | \ - PBF_READ_AHEAD | PBF_RUN_QUEUES); + PBF_READ_AHEAD | _PBF_RUN_QUEUES); BUG_ON(pb->pb_bn == XFS_BUF_DADDR_NULL); @@ -1378,8 +1359,8 @@ pagebuf_ioerror(pb, EIO); } - if (pb->pb_flags & PBF_RUN_QUEUES) { - pb->pb_flags &= ~PBF_RUN_QUEUES; + if (pb->pb_flags & _PBF_RUN_QUEUES) { + pb->pb_flags &= ~_PBF_RUN_QUEUES; if (atomic_read(&pb->pb_io_remaining) > 1) blk_run_address_space(pb->pb_target->pbr_mapping); } @@ -1434,25 +1415,6 @@ down(&pb->pb_iodonesema); PB_TRACE(pb, "iowaited", (long)pb->pb_error); return pb->pb_error; -} - -STATIC void * -pagebuf_mapout_locked( - xfs_buf_t *pb) -{ - void *old_addr = NULL; - - if (pb->pb_flags & PBF_MAPPED) { - if (pb->pb_flags & _PBF_ADDR_ALLOCATED) - old_addr = pb->pb_addr - pb->pb_offset; - pb->pb_addr = NULL; - pb->pb_flags &= ~(PBF_MAPPED | _PBF_ADDR_ALLOCATED); - } - - return old_addr; /* Caller must free the address space, - * we are under a spin lock, probably - * not safe to do vfree here - */ } caddr_t ===== fs/xfs/linux-2.6/xfs_buf.h 1.52 vs 1.53 ===== --- 1.52/fs/xfs/linux/xfs_buf.h 2004-04-21 07:12:41 +02:00 +++ 1.53/fs/xfs/linux/xfs_buf.h 2004-04-21 09:47:25 +02:00 @@ -73,26 +73,22 @@ PBF_ASYNC = (1 << 4), /* initiator will not wait for completion */ PBF_NONE = (1 << 5), /* buffer not read at all */ PBF_DELWRI = (1 << 6), /* buffer has dirty pages */ - PBF_STALE = (1 << 10), /* buffer has been staled, do not find it */ - PBF_FS_MANAGED = (1 << 11), /* filesystem controls freeing memory */ - PBF_FS_DATAIOD = (1 << 12), /* schedule IO completion on fs datad */ + PBF_STALE = (1 << 7), /* buffer has been staled, do not find it */ + PBF_FS_MANAGED = (1 << 8), /* filesystem controls freeing memory */ + PBF_FS_DATAIOD = (1 << 9), /* schedule IO completion on fs datad */ + PBF_FORCEIO = (1 << 10), /* ignore any cache state */ + PBF_FLUSH = (1 << 11), /* flush disk write cache */ + PBF_READ_AHEAD = (1 << 12), /* asynchronous read-ahead */ /* flags used only as arguments to access routines */ - PBF_LOCK = (1 << 13), /* lock requested */ - PBF_TRYLOCK = (1 << 14), /* lock requested, but do not wait */ - PBF_DONT_BLOCK = (1 << 15), /* do not block in current thread */ + PBF_LOCK = (1 << 14), /* lock requested */ + PBF_TRYLOCK = (1 << 15), /* lock requested, but do not wait */ + PBF_DONT_BLOCK = (1 << 16), /* do not block in current thread */ /* flags used only internally */ - _PBF_PAGECACHE = (1 << 16), /* backed by pagecache */ - _PBF_ADDR_ALLOCATED = (1 << 19), /* pb_addr space was allocated */ - _PBF_MEM_ALLOCATED = (1 << 20), /* underlying pages are allocated */ - _PBF_MEM_SLAB = (1 << 21), /* underlying pages are slab allocated */ - - PBF_FORCEIO = (1 << 22), /* ignore any cache state */ - PBF_FLUSH = (1 << 23), /* flush disk write cache */ - PBF_READ_AHEAD = (1 << 24), /* asynchronous read-ahead */ - PBF_RUN_QUEUES = (1 << 25), /* run block device task queue */ - + _PBF_PAGE_CACHE = (1 << 17),/* backed by pagecache */ + _PBF_KMEM_ALLOC = (1 << 18),/* backed by kmem_alloc() */ + _PBF_RUN_QUEUES = (1 << 19),/* run block device task queue */ } page_buf_flags_t; #define PBF_UPDATE (PBF_READ | PBF_WRITE) @@ -508,7 +504,7 @@ bp->pb_fspriv3 = mp; bp->pb_strat = xfs_bdstrat_cb; xfs_buf_undelay(bp); - return pagebuf_iostart(bp, PBF_WRITE | PBF_ASYNC | PBF_RUN_QUEUES); + return pagebuf_iostart(bp, PBF_WRITE | PBF_ASYNC | _PBF_RUN_QUEUES); } static inline void xfs_buf_relse(xfs_buf_t *bp) @@ -545,7 +541,7 @@ int error = 0; if (!iowait) - pb->pb_flags |= PBF_RUN_QUEUES; + pb->pb_flags |= _PBF_RUN_QUEUES; xfs_buf_undelay(pb); pagebuf_iostrategy(pb);