direct-io.hg
changeset 6530:fa0754a9f64f
Merge.
line diff
43.1 --- a/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_64 Tue Aug 23 12:03:21 2005 -0700 43.2 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_64 Wed Aug 24 13:29:21 2005 -0700 43.3 @@ -674,10 +674,10 @@ CONFIG_EXT2_FS=y 43.4 CONFIG_EXT2_FS_XATTR=y 43.5 CONFIG_EXT2_FS_POSIX_ACL=y 43.6 CONFIG_EXT2_FS_SECURITY=y 43.7 -CONFIG_EXT3_FS=m 43.8 +CONFIG_EXT3_FS=y 43.9 CONFIG_EXT3_FS_XATTR=y 43.10 -CONFIG_EXT3_FS_POSIX_ACL=y 43.11 -CONFIG_EXT3_FS_SECURITY=y 43.12 +# CONFIG_EXT3_FS_POSIX_ACL is not set 43.13 +# CONFIG_EXT3_FS_SECURITY is not set 43.14 CONFIG_JBD=m 43.15 # CONFIG_JBD_DEBUG is not set 43.16 CONFIG_FS_MBCACHE=y
80.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/ia32/syscall32.c Tue Aug 23 12:03:21 2005 -0700 80.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/ia32/syscall32.c Wed Aug 24 13:29:21 2005 -0700 80.3 @@ -128,8 +128,12 @@ static int __init init_syscall32(void) 80.4 #endif 80.5 return 0; 80.6 } 80.7 - 80.8 -__initcall(init_syscall32); 80.9 + 80.10 +/* 80.11 + * This must be done early in case we have an initrd containing 32-bit 80.12 + * binaries (e.g., hotplug). This could be pushed upstream to arch/x86_64. 80.13 + */ 80.14 +core_initcall(init_syscall32); 80.15 80.16 /* May not be __init: called during resume */ 80.17 void syscall32_cpu_init(void)
87.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/head.S Tue Aug 23 12:03:21 2005 -0700 87.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/head.S Wed Aug 24 13:29:21 2005 -0700 87.3 @@ -43,7 +43,7 @@ ENTRY(_start) 87.4 cld 87.5 /* Copy the necessary stuff from xen_start_info structure. */ 87.6 movq $xen_start_info_union,%rdi 87.7 - movq $64,%rcx /* sizeof (union xen_start_info_union) / sizeof (long) */ 87.8 + movq $256,%rcx 87.9 rep movsq 87.10 87.11 #ifdef CONFIG_SMP
93.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c Tue Aug 23 12:03:21 2005 -0700 93.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c Wed Aug 24 13:29:21 2005 -0700 93.3 @@ -428,8 +428,9 @@ static void __init contig_initmem_init(v 93.4 { 93.5 unsigned long bootmap_size = init_bootmem(start_pfn, end_pfn); 93.6 free_bootmem(0, end_pfn << PAGE_SHIFT); 93.7 - /* XXX KAF: Why can't we leave low 1MB of memory free? */ 93.8 - reserve_bootmem(0, (PFN_PHYS(start_pfn) + bootmap_size + PAGE_SIZE-1)); 93.9 + reserve_bootmem(HIGH_MEMORY, 93.10 + (PFN_PHYS(start_pfn) + bootmap_size + PAGE_SIZE-1) 93.11 + - HIGH_MEMORY); 93.12 } 93.13 #else 93.14 static void __init contig_initmem_init(void)
102.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/mm/init.c Tue Aug 23 12:03:21 2005 -0700 102.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/mm/init.c Wed Aug 24 13:29:21 2005 -0700 102.3 @@ -441,6 +441,31 @@ static inline void __set_pte(pte_t *dst, 102.4 *dst = val; 102.5 } 102.6 102.7 +static inline int make_readonly(unsigned long paddr) 102.8 +{ 102.9 + int readonly = 0; 102.10 + 102.11 + /* Make new page tables read-only. */ 102.12 + if ((paddr < ((table_start << PAGE_SHIFT) + tables_space)) && 102.13 + (paddr >= (table_start << PAGE_SHIFT))) 102.14 + readonly = 1; 102.15 + 102.16 + /* Make old page tables read-only. */ 102.17 + if ((paddr < ((xen_start_info.pt_base - __START_KERNEL_map) + 102.18 + (xen_start_info.nr_pt_frames << PAGE_SHIFT))) && 102.19 + (paddr >= (xen_start_info.pt_base - __START_KERNEL_map))) 102.20 + readonly = 1; 102.21 + 102.22 + /* 102.23 + * No need for writable mapping of kernel image. This also ensures that 102.24 + * page and descriptor tables embedded inside don't have writable mappings. 102.25 + */ 102.26 + if ((paddr >= __pa_symbol(&_text)) && (paddr < __pa_symbol(&_end))) 102.27 + readonly = 1; 102.28 + 102.29 + return readonly; 102.30 +} 102.31 + 102.32 void __init phys_pud_init(pud_t *pud, unsigned long address, unsigned long end) 102.33 { 102.34 long i, j, k; 102.35 @@ -477,9 +502,7 @@ void __init phys_pud_init(pud_t *pud, un 102.36 pte = alloc_low_page(&pte_phys); 102.37 pte_save = pte; 102.38 for (k = 0; k < PTRS_PER_PTE; pte++, k++, paddr += PTE_SIZE) { 102.39 - if (paddr < (table_start << PAGE_SHIFT) 102.40 - + tables_space) 102.41 - { 102.42 + if (make_readonly(paddr)) { 102.43 __set_pte(pte, 102.44 __pte(paddr | (_KERNPG_TABLE & ~_PAGE_RW))); 102.45 continue;
111.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Tue Aug 23 12:03:21 2005 -0700 111.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Wed Aug 24 13:29:21 2005 -0700 111.3 @@ -75,24 +75,12 @@ static void frontend_changed(struct xenb 111.4 err = xenbus_gather(be->frontpath, "grant-id", "%lu", &sharedmfn, 111.5 "event-channel", "%u", &evtchn, NULL); 111.6 if (err) { 111.7 - xenbus_dev_error(be->dev, err, 111.8 + xenbus_dev_error(be->dev, err, 111.9 "reading %s/grant-id and event-channel", 111.10 be->frontpath); 111.11 return; 111.12 } 111.13 111.14 - /* Domains must use same shared frame for all vbds. */ 111.15 - if (evtchn != be->blkif->remote_evtchn || 111.16 - sharedmfn != be->blkif->shmem_frame) { 111.17 - xenbus_dev_error(be->dev, err, 111.18 - "Shared frame/evtchn %li/%u not same as" 111.19 - " old %li/%u", 111.20 - sharedmfn, evtchn, 111.21 - be->blkif->shmem_frame, 111.22 - be->blkif->remote_evtchn); 111.23 - return; 111.24 - } 111.25 - 111.26 /* Supply the information about the device the frontend needs */ 111.27 err = xenbus_transaction_start(be->dev->nodename); 111.28 if (err) { 111.29 @@ -189,6 +177,9 @@ static void backend_changed(struct xenbu 111.30 err = register_xenbus_watch(&be->watch); 111.31 if (err) { 111.32 be->watch.node = NULL; 111.33 + xenbus_dev_error(dev, err, 111.34 + "adding frontend watch on %s", 111.35 + be->frontpath); 111.36 goto device_fail; 111.37 } 111.38 } 111.39 @@ -223,12 +214,15 @@ static void backend_changed(struct xenbu 111.40 if (IS_ERR(be->blkif)) { 111.41 err = PTR_ERR(be->blkif); 111.42 be->blkif = NULL; 111.43 + xenbus_dev_error(dev, err, "creating block interface"); 111.44 goto device_fail; 111.45 } 111.46 111.47 err = vbd_create(be->blkif, handle, be->pdev, be->readonly); 111.48 - if (err) 111.49 + if (err) { 111.50 + xenbus_dev_error(dev, err, "creating vbd structure"); 111.51 goto device_fail; 111.52 + } 111.53 111.54 frontend_changed(&be->watch, be->frontpath); 111.55 } 111.56 @@ -250,8 +244,10 @@ static int blkback_probe(struct xenbus_d 111.57 int err; 111.58 111.59 be = kmalloc(sizeof(*be), GFP_KERNEL); 111.60 - if (!be) 111.61 + if (!be) { 111.62 + xenbus_dev_error(dev, -ENOMEM, "allocating backend structure"); 111.63 return -ENOMEM; 111.64 + } 111.65 111.66 memset(be, 0, sizeof(*be)); 111.67 111.68 @@ -259,8 +255,11 @@ static int blkback_probe(struct xenbus_d 111.69 be->backend_watch.node = dev->nodename; 111.70 be->backend_watch.callback = backend_changed; 111.71 err = register_xenbus_watch(&be->backend_watch); 111.72 - if (err) 111.73 + if (err) { 111.74 + xenbus_dev_error(dev, err, "adding backend watch on %s", 111.75 + dev->nodename); 111.76 goto free_be; 111.77 + } 111.78 111.79 dev->data = be; 111.80
112.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Tue Aug 23 12:03:21 2005 -0700 112.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Wed Aug 24 13:29:21 2005 -0700 112.3 @@ -1165,8 +1165,10 @@ static int talk_to_backend(struct xenbus 112.4 112.5 /* Create shared ring, alloc event channel. */ 112.6 err = setup_blkring(dev, info); 112.7 - if (err) 112.8 + if (err) { 112.9 + xenbus_dev_error(dev, err, "setting up block ring"); 112.10 goto out; 112.11 + } 112.12 112.13 err = xenbus_transaction_start(dev->nodename); 112.14 if (err) { 112.15 @@ -1329,9 +1331,9 @@ static int wait_for_blkif(void) 112.16 int i; 112.17 112.18 /* 112.19 - * We should read 'nr_interfaces' from response message and wait 112.20 - * for notifications before proceeding. For now we assume that we 112.21 - * will be notified of exactly one interface. 112.22 + * We should figure out how many and which devices we need to 112.23 + * proceed and only wait for those. For now, continue once the 112.24 + * first device is around. 112.25 */ 112.26 for ( i=0; blkif_state != BLKIF_STATE_CONNECTED && (i < 10*HZ); i++ ) 112.27 {
124.1 --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Tue Aug 23 12:03:21 2005 -0700 124.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Wed Aug 24 13:29:21 2005 -0700 124.3 @@ -200,6 +200,7 @@ static char *be_state_name[] = { 124.4 [BEST_CONNECTED] = "connected", 124.5 }; 124.6 124.7 +#define DEBUG 124.8 #ifdef DEBUG 124.9 #define DPRINTK(fmt, args...) \ 124.10 printk(KERN_ALERT "xen_net (%s:%d) " fmt, __FUNCTION__, __LINE__, ##args) 124.11 @@ -919,6 +920,7 @@ static void vif_show(struct net_private 124.12 /* Send a connect message to xend to tell it to bring up the interface. */ 124.13 static void send_interface_connect(struct net_private *np) 124.14 { 124.15 + int err; 124.16 ctrl_msg_t cmsg = { 124.17 .type = CMSG_NETIF_FE, 124.18 .subtype = CMSG_NETIF_FE_INTERFACE_CONNECT, 124.19 @@ -929,24 +931,22 @@ static void send_interface_connect(struc 124.20 msg->handle = np->handle; 124.21 msg->tx_shmem_frame = virt_to_mfn(np->tx); 124.22 #ifdef CONFIG_XEN_NETDEV_GRANT_TX 124.23 - msg->tx_shmem_ref = (u32)gnttab_claim_grant_reference(&gref_tx_head); 124.24 - if(msg->tx_shmem_ref < 0) { 124.25 - printk(KERN_ALERT "#### netfront can't claim tx_shmem reference\n"); 124.26 + err = gnttab_grant_foreign_access(rdomid, msg->tx_shmem_frame, 0); 124.27 + if (err < 0) { 124.28 + printk(KERN_ALERT "#### netfront can't grant access to tx_shmem\n"); 124.29 BUG(); 124.30 } 124.31 - gnttab_grant_foreign_access_ref (msg->tx_shmem_ref, rdomid, 124.32 - msg->tx_shmem_frame, 0); 124.33 + msg->tx_shmem_ref = err; 124.34 #endif 124.35 124.36 msg->rx_shmem_frame = virt_to_mfn(np->rx); 124.37 #ifdef CONFIG_XEN_NETDEV_GRANT_RX 124.38 - msg->rx_shmem_ref = (u32)gnttab_claim_grant_reference(&gref_rx_head); 124.39 - if(msg->rx_shmem_ref < 0) { 124.40 - printk(KERN_ALERT "#### netfront can't claim rx_shmem reference\n"); 124.41 + err = gnttab_grant_foreign_access(rdomid, msg->rx_shmem_frame, 0); 124.42 + if (err < 0) { 124.43 + printk(KERN_ALERT "#### netfront can't grant access to rx_shmem\n"); 124.44 BUG(); 124.45 } 124.46 - gnttab_grant_foreign_access_ref (msg->rx_shmem_ref, rdomid, 124.47 - msg->rx_shmem_frame, 0); 124.48 + msg->rx_shmem_ref = err; 124.49 #endif 124.50 124.51 ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE); 124.52 @@ -1416,8 +1416,8 @@ static int __init netif_init(void) 124.53 if (xen_start_info.flags & SIF_INITDOMAIN) 124.54 return 0; 124.55 #ifdef CONFIG_XEN_NETDEV_GRANT_TX 124.56 - /* A grant for every ring slot, plus one for the ring itself */ 124.57 - if (gnttab_alloc_grant_references(NETIF_TX_RING_SIZE + 1, 124.58 + /* A grant for every ring slot */ 124.59 + if (gnttab_alloc_grant_references(NETIF_TX_RING_SIZE, 124.60 &gref_tx_head) < 0) { 124.61 printk(KERN_ALERT "#### netfront can't alloc tx grant refs\n"); 124.62 return 1; 124.63 @@ -1425,8 +1425,8 @@ static int __init netif_init(void) 124.64 printk(KERN_ALERT "Netdev frontend (TX) is using grant tables.\n"); 124.65 #endif 124.66 #ifdef CONFIG_XEN_NETDEV_GRANT_RX 124.67 - /* A grant for every ring slot, plus one for the ring itself */ 124.68 - if (gnttab_alloc_grant_references(NETIF_RX_RING_SIZE + 1, 124.69 + /* A grant for every ring slot */ 124.70 + if (gnttab_alloc_grant_references(NETIF_RX_RING_SIZE, 124.71 &gref_rx_head) < 0) { 124.72 printk(KERN_ALERT "#### netfront can't alloc rx grant refs\n"); 124.73 return 1;
134.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Tue Aug 23 12:03:21 2005 -0700 134.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Wed Aug 24 13:29:21 2005 -0700 134.3 @@ -627,6 +627,8 @@ int do_xenbus_probe(void *unused) 134.4 /* Watch for changes. */ 134.5 register_xenbus_watch(&fe_watch); 134.6 register_xenbus_watch(&be_watch); 134.7 + /* Notify others that xenstore is up */ 134.8 + notifier_call_chain(&xenstore_chain, 0, 0); 134.9 up(&xenbus_lock); 134.10 return 0; 134.11 } 134.12 @@ -637,7 +639,7 @@ static int __init xenbus_probe_init(void 134.13 bus_register(&xenbus_backend.bus); 134.14 device_register(&xenbus_frontend.dev); 134.15 device_register(&xenbus_backend.dev); 134.16 - 134.17 + 134.18 if (!xen_start_info.store_evtchn) 134.19 return 0; 134.20
144.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_post.h Tue Aug 23 12:03:21 2005 -0700 144.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_post.h Wed Aug 24 13:29:21 2005 -0700 144.3 @@ -8,23 +8,12 @@ 144.4 144.5 static char * __init machine_specific_memory_setup(void) 144.6 { 144.7 - char *who; 144.8 - unsigned long start_pfn, max_pfn; 144.9 - 144.10 - who = "Xen"; 144.11 - 144.12 - /* In dom0, we have to start the fake e820 map above the first 144.13 - * 1MB, in other domains, it can start at 0. */ 144.14 - if (xen_start_info.flags & SIF_INITDOMAIN) 144.15 - start_pfn = 0x100; 144.16 - else 144.17 - start_pfn = 0; 144.18 - max_pfn = xen_start_info.nr_pages; 144.19 + unsigned long max_pfn = xen_start_info.nr_pages; 144.20 144.21 e820.nr_map = 0; 144.22 - add_memory_region(PFN_PHYS(start_pfn), PFN_PHYS(max_pfn) - PFN_PHYS(start_pfn), E820_RAM); 144.23 + add_memory_region(0, PFN_PHYS(max_pfn), E820_RAM); 144.24 144.25 - return who; 144.26 + return "Xen"; 144.27 } 144.28 144.29 void __init machine_specific_modify_cpu_capabilities(struct cpuinfo_x86 *c)
379.1 --- a/tools/xenstore/testsuite/02directory.test Tue Aug 23 12:03:21 2005 -0700 379.2 +++ b/tools/xenstore/testsuite/02directory.test Wed Aug 24 13:29:21 2005 -0700 379.3 @@ -32,3 +32,16 @@ expect mkdir failed: File exists 379.4 mkdir /dir 379.5 expect mkdir failed: File exists 379.6 mkdir /dir/test2 379.7 + 379.8 +# Mkdir implicitly creates directories. 379.9 +mkdir /dir/1/2/3/4 379.10 +expect test2 379.11 +expect 1 379.12 +dir /dir 379.13 +expect 2 379.14 +dir /dir/1 379.15 +expect 3 379.16 +dir /dir/1/2 379.17 +expect 4 379.18 +dir /dir/1/2/3 379.19 +dir /dir/1/2/3/4
380.1 --- a/tools/xenstore/testsuite/03write.test Tue Aug 23 12:03:21 2005 -0700 380.2 +++ b/tools/xenstore/testsuite/03write.test Wed Aug 24 13:29:21 2005 -0700 380.3 @@ -18,3 +18,22 @@ read /test 380.4 write /test create contents3 380.5 expect contents3 380.6 read /test 380.7 + 380.8 +# Write should implicitly create directories 380.9 +write /dir/test create contents 380.10 +expect test 380.11 +dir /dir 380.12 +expect contents 380.13 +read /dir/test 380.14 +write /dir/1/2/3/4 excl contents4 380.15 +expect test 380.16 +expect 1 380.17 +dir /dir 380.18 +expect 2 380.19 +dir /dir/1 380.20 +expect 3 380.21 +dir /dir/1/2 380.22 +expect 4 380.23 +dir /dir/1/2/3 380.24 +expect contents4 380.25 +read /dir/1/2/3/4
381.1 --- a/tools/xenstore/testsuite/06dirpermissions.test Tue Aug 23 12:03:21 2005 -0700 381.2 +++ b/tools/xenstore/testsuite/06dirpermissions.test Wed Aug 24 13:29:21 2005 -0700 381.3 @@ -117,3 +117,11 @@ setid 3 381.4 write /dir/subdir/subfile excl contents 381.5 expect 3 READ/WRITE 381.6 getperm /dir/subdir/subfile 381.7 + 381.8 +# Inheritence works through multiple directories, too. 381.9 +write /dir/subdir/1/2/3/4 excl contents 381.10 +expect 3 READ/WRITE 381.11 +getperm /dir/subdir/1/2/3/4 381.12 +mkdir /dir/subdir/a/b/c/d 381.13 +expect 3 READ/WRITE 381.14 +getperm /dir/subdir/a/b/c/d
382.1 --- a/tools/xenstore/testsuite/test.sh Tue Aug 23 12:03:21 2005 -0700 382.2 +++ b/tools/xenstore/testsuite/test.sh Wed Aug 24 13:29:21 2005 -0700 382.3 @@ -8,7 +8,7 @@ run_test() 382.4 rm -rf $XENSTORED_ROOTDIR 382.5 mkdir $XENSTORED_ROOTDIR 382.6 if [ $VALGRIND -eq 1 ]; then 382.7 - valgrind -q --logfile-fd=3 ./xenstored_test --output-pid --trace-file=testsuite/tmp/trace --no-fork 3>testsuite/tmp/vgout > /tmp/pid 2> testsuite/tmp/xenstored_errors & 382.8 + valgrind --suppressions=testsuite/vg-suppressions -q ./xenstored_test --output-pid --trace-file=testsuite/tmp/trace --no-fork > /tmp/pid 2> testsuite/tmp/xenstored_errors & 382.9 while [ ! -s /tmp/pid ]; do sleep 0; done 382.10 PID=`cat /tmp/pid` 382.11 rm /tmp/pid 382.12 @@ -17,10 +17,10 @@ run_test() 382.13 PID=`./xenstored_test --output-pid --trace-file=testsuite/tmp/trace` 382.14 fi 382.15 if ./xs_test $2 $1; then 382.16 - if [ -s testsuite/tmp/vgout ]; then 382.17 + if [ -s testsuite/tmp/xenstored_errors ]; then 382.18 kill $PID 382.19 - echo VALGRIND errors: 382.20 - cat testsuite/tmp/vgout 382.21 + echo Errors: 382.22 + cat testsuite/tmp/xenstored_errors 382.23 return 1 382.24 fi 382.25 echo shutdown | ./xs_test 382.26 @@ -52,11 +52,10 @@ for f in testsuite/[0-9]*.test $SLOWTEST 382.27 case `basename $f` in $MATCH) RUN=1;; esac 382.28 [ -n "$RUN" ] || continue 382.29 382.30 - if run_test $f > /dev/null; then 382.31 + if run_test $f -x >/tmp/out; then 382.32 echo -n . 382.33 else 382.34 - echo Test $f failed, running verbosely... 382.35 - run_test $f -x || true 382.36 + cat /tmp/out 382.37 # That will have filled the screen, repeat message. 382.38 echo Test $f failed 382.39 exit 1
386.1 --- a/tools/xenstore/xenstored_core.c Tue Aug 23 12:03:21 2005 -0700 386.2 +++ b/tools/xenstore/xenstored_core.c Wed Aug 24 13:29:21 2005 -0700 386.3 @@ -423,14 +423,24 @@ static char *node_dir(struct transaction 386.4 return node_dir_inside_transaction(trans, node); 386.5 } 386.6 386.7 +static char *datafile(const char *dir) 386.8 +{ 386.9 + return talloc_asprintf(dir, "%s/.data", dir); 386.10 +} 386.11 + 386.12 static char *node_datafile(struct transaction *trans, const char *node) 386.13 { 386.14 - return talloc_asprintf(node, "%s/.data", node_dir(trans, node)); 386.15 + return datafile(node_dir(trans, node)); 386.16 +} 386.17 + 386.18 +static char *permfile(const char *dir) 386.19 +{ 386.20 + return talloc_asprintf(dir, "%s/.perms", dir); 386.21 } 386.22 386.23 static char *node_permfile(struct transaction *trans, const char *node) 386.24 { 386.25 - return talloc_asprintf(node, "%s/.perms", node_dir(trans, node)); 386.26 + return permfile(node_dir(trans, node)); 386.27 } 386.28 386.29 struct buffered_data *new_buffer(void *ctx) 386.30 @@ -557,15 +567,14 @@ static const char *onearg(struct buffere 386.31 } 386.32 386.33 /* If it fails, returns NULL and sets errno. */ 386.34 -static struct xs_permissions *get_perms(struct transaction *transaction, 386.35 - const char *node, unsigned int *num) 386.36 +static struct xs_permissions *get_perms(const char *dir, unsigned int *num) 386.37 { 386.38 unsigned int size; 386.39 char *strings; 386.40 struct xs_permissions *ret; 386.41 int *fd; 386.42 386.43 - fd = talloc_open(node_permfile(transaction, node), O_RDONLY, 0); 386.44 + fd = talloc_open(permfile(dir), O_RDONLY, 0); 386.45 if (!fd) 386.46 return NULL; 386.47 strings = read_all(fd, &size); 386.48 @@ -573,14 +582,14 @@ static struct xs_permissions *get_perms( 386.49 return NULL; 386.50 386.51 *num = xs_count_strings(strings, size); 386.52 - ret = talloc_array(node, struct xs_permissions, *num); 386.53 + ret = talloc_array(dir, struct xs_permissions, *num); 386.54 if (!xs_strings_to_perms(ret, *num, strings)) 386.55 - corrupt(NULL, "Permissions corrupt for %s", node); 386.56 + corrupt(NULL, "Permissions corrupt for %s", dir); 386.57 386.58 return ret; 386.59 } 386.60 386.61 -static char *perms_to_strings(const char *node, 386.62 +static char *perms_to_strings(const void *ctx, 386.63 struct xs_permissions *perms, unsigned int num, 386.64 unsigned int *len) 386.65 { 386.66 @@ -592,7 +601,7 @@ static char *perms_to_strings(const char 386.67 if (!xs_perm_to_string(&perms[i], buffer)) 386.68 return NULL; 386.69 386.70 - strings = talloc_realloc(node, strings, char, 386.71 + strings = talloc_realloc(ctx, strings, char, 386.72 *len + strlen(buffer) + 1); 386.73 strcpy(strings + *len, buffer); 386.74 *len += strlen(buffer) + 1; 386.75 @@ -625,16 +634,23 @@ int destroy_path(void *path) 386.76 return 0; 386.77 } 386.78 386.79 +/* Create a self-destructing temporary path */ 386.80 +static char *temppath(const char *path) 386.81 +{ 386.82 + char *tmppath = talloc_asprintf(path, "%s.tmp", path); 386.83 + talloc_set_destructor(tmppath, destroy_path); 386.84 + return tmppath; 386.85 +} 386.86 + 386.87 /* Create a self-destructing temporary file */ 386.88 static char *tempfile(const char *path, void *contents, unsigned int len) 386.89 { 386.90 int *fd; 386.91 - char *tmppath = talloc_asprintf(path, "%s.tmp", path); 386.92 + char *tmppath = temppath(path); 386.93 386.94 fd = talloc_open(tmppath, O_WRONLY|O_CREAT|O_EXCL, 0640); 386.95 if (!fd) 386.96 return NULL; 386.97 - talloc_set_destructor(tmppath, destroy_path); 386.98 if (!xs_write_all(*fd, contents, len)) 386.99 return NULL; 386.100 386.101 @@ -732,7 +748,7 @@ static enum xs_perm_type ask_parents(str 386.102 386.103 do { 386.104 node = get_parent(node); 386.105 - perms = get_perms(conn->transaction, node, &num); 386.106 + perms = get_perms(node_dir(conn->transaction, node), &num); 386.107 if (perms) 386.108 break; 386.109 } while (!streq(node, "/")); 386.110 @@ -788,7 +804,7 @@ bool check_node_perms(struct connection 386.111 return false; 386.112 } 386.113 386.114 - perms = get_perms(conn->transaction, node, &num); 386.115 + perms = get_perms(node_dir(conn->transaction, node), &num); 386.116 386.117 if (perms) { 386.118 if (perm_for_id(conn->id, perms, num) & perm) 386.119 @@ -875,44 +891,64 @@ static void do_read(struct connection *c 386.120 send_reply(conn, XS_READ, value, size); 386.121 } 386.122 386.123 -/* Create a new directory. Optionally put data in it (if data != NULL) */ 386.124 -static bool new_directory(struct connection *conn, 386.125 - const char *node, void *data, unsigned int datalen) 386.126 +/* Commit this directory, eg. comitting a/b.tmp/c causes a/b.tmp -> a.b */ 386.127 +static bool commit_dir(char *dir) 386.128 +{ 386.129 + char *dot, *slash, *dest; 386.130 + 386.131 + dot = strrchr(dir, '.'); 386.132 + slash = strchr(dot, '/'); 386.133 + if (slash) 386.134 + *slash = '\0'; 386.135 + 386.136 + dest = talloc_asprintf(dir, "%.*s", dot - dir, dir); 386.137 + return rename(dir, dest) == 0; 386.138 +} 386.139 + 386.140 +/* Create a temporary directory. Put data in it (if data != NULL) */ 386.141 +static char *tempdir(struct connection *conn, 386.142 + const char *node, void *data, unsigned int datalen) 386.143 { 386.144 struct xs_permissions *perms; 386.145 char *permstr; 386.146 unsigned int num, len; 386.147 int *fd; 386.148 - char *dir = node_dir(conn->transaction, node); 386.149 + char *dir; 386.150 386.151 - if (mkdir(dir, 0750) != 0) 386.152 - return false; 386.153 + dir = temppath(node_dir(conn->transaction, node)); 386.154 + if (mkdir(dir, 0750) != 0) { 386.155 + if (errno != ENOENT) 386.156 + return NULL; 386.157 386.158 - /* Set destructor so we clean up if neccesary. */ 386.159 - talloc_set_destructor(dir, destroy_path); 386.160 + dir = tempdir(conn, get_parent(node), NULL, 0); 386.161 + if (!dir) 386.162 + return NULL; 386.163 386.164 - perms = get_perms(conn->transaction, get_parent(node), &num); 386.165 + dir = talloc_asprintf(dir, "%s%s", dir, strrchr(node, '/')); 386.166 + if (mkdir(dir, 0750) != 0) 386.167 + return NULL; 386.168 + talloc_set_destructor(dir, destroy_path); 386.169 + } 386.170 + 386.171 + perms = get_perms(get_parent(dir), &num); 386.172 + assert(perms); 386.173 /* Domains own what they create. */ 386.174 if (conn->id) 386.175 perms->id = conn->id; 386.176 386.177 permstr = perms_to_strings(dir, perms, num, &len); 386.178 - fd = talloc_open(node_permfile(conn->transaction, node), 386.179 - O_WRONLY|O_CREAT|O_EXCL, 0640); 386.180 + fd = talloc_open(permfile(dir), O_WRONLY|O_CREAT|O_EXCL, 0640); 386.181 if (!fd || !xs_write_all(*fd, permstr, len)) 386.182 - return false; 386.183 + return NULL; 386.184 386.185 if (data) { 386.186 - char *datapath = node_datafile(conn->transaction, node); 386.187 + char *datapath = datafile(dir); 386.188 386.189 fd = talloc_open(datapath, O_WRONLY|O_CREAT|O_EXCL, 0640); 386.190 if (!fd || !xs_write_all(*fd, data, datalen)) 386.191 - return false; 386.192 + return NULL; 386.193 } 386.194 - 386.195 - /* Finished! */ 386.196 - talloc_set_destructor(dir, NULL); 386.197 - return true; 386.198 + return dir; 386.199 } 386.200 386.201 /* path, flags, data... */ 386.202 @@ -959,6 +995,8 @@ static void do_write(struct connection * 386.203 } 386.204 386.205 if (lstat(node_dir(conn->transaction, node), &st) != 0) { 386.206 + char *dir; 386.207 + 386.208 /* Does not exist... */ 386.209 if (errno != ENOENT) { 386.210 send_error(conn, errno); 386.211 @@ -971,10 +1009,12 @@ static void do_write(struct connection * 386.212 return; 386.213 } 386.214 386.215 - if (!new_directory(conn, node, in->buffer + offset, datalen)) { 386.216 + dir = tempdir(conn, node, in->buffer + offset, datalen); 386.217 + if (!dir || !commit_dir(dir)) { 386.218 send_error(conn, errno); 386.219 return; 386.220 } 386.221 + 386.222 } else { 386.223 /* Exists... */ 386.224 if (streq(vec[1], XS_WRITE_CREATE_EXCL)) { 386.225 @@ -999,6 +1039,9 @@ static void do_write(struct connection * 386.226 386.227 static void do_mkdir(struct connection *conn, const char *node) 386.228 { 386.229 + char *dir; 386.230 + struct stat st; 386.231 + 386.232 node = canonicalize(conn, node); 386.233 if (!check_node_perms(conn, node, XS_PERM_WRITE|XS_PERM_ENOENT_OK)) { 386.234 send_error(conn, errno); 386.235 @@ -1013,7 +1056,14 @@ static void do_mkdir(struct connection * 386.236 if (transaction_block(conn, node)) 386.237 return; 386.238 386.239 - if (!new_directory(conn, node, NULL, 0)) { 386.240 + /* Must not already exist. */ 386.241 + if (lstat(node_dir(conn->transaction, node), &st) == 0) { 386.242 + send_error(conn, EEXIST); 386.243 + return; 386.244 + } 386.245 + 386.246 + dir = tempdir(conn, node, NULL, 0); 386.247 + if (!dir || !commit_dir(dir)) { 386.248 send_error(conn, errno); 386.249 return; 386.250 } 386.251 @@ -1073,7 +1123,7 @@ static void do_get_perms(struct connecti 386.252 return; 386.253 } 386.254 386.255 - perms = get_perms(conn->transaction, node, &num); 386.256 + perms = get_perms(node_dir(conn->transaction, node), &num); 386.257 if (!perms) { 386.258 send_error(conn, errno); 386.259 return;
398.1 --- a/tools/xenstore/xs_random.c Tue Aug 23 12:03:21 2005 -0700 398.2 +++ b/tools/xenstore/xs_random.c Wed Aug 24 13:29:21 2005 -0700 398.3 @@ -303,6 +303,34 @@ static bool file_set_perms(struct file_o 398.4 return true; 398.5 } 398.6 398.7 +static char *parent_filename(const char *name) 398.8 +{ 398.9 + char *slash = strrchr(name + 1, '/'); 398.10 + if (!slash) 398.11 + return talloc_strdup(name, "/"); 398.12 + return talloc_asprintf(name, "%.*s", slash-name, name); 398.13 +} 398.14 + 398.15 +static void make_dirs(const char *filename) 398.16 +{ 398.17 + struct stat st; 398.18 + 398.19 + if (lstat(filename, &st) == 0 && S_ISREG(st.st_mode)) 398.20 + convert_to_dir(filename); 398.21 + 398.22 + if (mkdir(filename, 0700) == 0) { 398.23 + init_perms(filename); 398.24 + return; 398.25 + } 398.26 + if (errno == EEXIST) 398.27 + return; 398.28 + 398.29 + make_dirs(parent_filename(filename)); 398.30 + if (mkdir(filename, 0700) != 0) 398.31 + barf_perror("Failed to mkdir %s", filename); 398.32 + init_perms(filename); 398.33 +} 398.34 + 398.35 static bool file_write(struct file_ops_info *info, 398.36 const char *path, const void *data, 398.37 unsigned int len, int createflags) 398.38 @@ -329,6 +357,9 @@ static bool file_write(struct file_ops_i 398.39 } 398.40 } 398.41 398.42 + if (createflags & O_CREAT) 398.43 + make_dirs(parent_filename(filename)); 398.44 + 398.45 fd = open(filename, createflags|O_TRUNC|O_WRONLY, 0600); 398.46 if (fd < 0) { 398.47 /* FIXME: Another hack. */ 398.48 @@ -352,6 +383,7 @@ static bool file_mkdir(struct file_ops_i 398.49 if (!write_ok(info, path)) 398.50 return false; 398.51 398.52 + make_dirs(parent_filename(dirname)); 398.53 if (mkdir(dirname, 0700) != 0) 398.54 return false; 398.55 398.56 @@ -420,7 +452,7 @@ static bool file_transaction_end(struct 398.57 } 398.58 398.59 if (abort) { 398.60 - cmd = talloc_asprintf(NULL, "rm -r %s", info->transact_base); 398.61 + cmd = talloc_asprintf(NULL, "rm -rf %s", info->transact_base); 398.62 do_command(cmd); 398.63 goto success; 398.64 } 398.65 @@ -1004,8 +1036,8 @@ static void setup_xs_ops(void) 398.66 } else { 398.67 dup2(fds[1], STDOUT_FILENO); 398.68 close(fds[0]); 398.69 -#if 0 398.70 - execlp("valgrind", "valgrind", "xenstored_test", "--output-pid", 398.71 +#if 1 398.72 + execlp("valgrind", "valgrind", "-q", "--suppressions=testsuite/vg-suppressions", "xenstored_test", "--output-pid", 398.73 "--no-fork", NULL); 398.74 #else 398.75 execlp("./xenstored_test", "xenstored_test", "--output-pid",
440.1 --- a/xen/arch/x86/cpu/amd.c Tue Aug 23 12:03:21 2005 -0700 440.2 +++ b/xen/arch/x86/cpu/amd.c Wed Aug 24 13:29:21 2005 -0700 440.3 @@ -9,6 +9,20 @@ 440.4 440.5 #include "cpu.h" 440.6 440.7 +/* 440.8 + * amd_flush_filter={on,off}. Forcibly Enable or disable the TLB flush 440.9 + * filter on AMD 64-bit processors. 440.10 + */ 440.11 +static int flush_filter_force; 440.12 +static void flush_filter(char *s) 440.13 +{ 440.14 + if (!strcmp(s, "off")) 440.15 + flush_filter_force = -1; 440.16 + if (!strcmp(s, "on")) 440.17 + flush_filter_force = 1; 440.18 +} 440.19 +custom_param("amd_flush_filter", flush_filter); 440.20 + 440.21 #define num_physpages 0 440.22 440.23 /* 440.24 @@ -192,6 +206,21 @@ static void __init init_amd(struct cpuin 440.25 break; 440.26 } 440.27 440.28 + if (c->x86 == 15) { 440.29 + rdmsr(MSR_K7_HWCR, l, h); 440.30 + printk(KERN_INFO "CPU%d: AMD Flush Filter %sabled", 440.31 + smp_processor_id(), (l & (1<<6)) ? "dis" : "en"); 440.32 + if ((flush_filter_force > 0) && (l & (1<<6))) { 440.33 + l &= ~(1<<6); 440.34 + printk(" -> Forcibly enabled"); 440.35 + } else if ((flush_filter_force < 0) && !(l & (1<<6))) { 440.36 + l |= 1<<6; 440.37 + printk(" -> Forcibly disabled"); 440.38 + } 440.39 + wrmsr(MSR_K7_HWCR, l, h); 440.40 + printk("\n"); 440.41 + } 440.42 + 440.43 display_cacheinfo(c); 440.44 440.45 if (cpuid_eax(0x80000000) >= 0x80000008) {
448.1 --- a/xen/arch/x86/mm.c Tue Aug 23 12:03:21 2005 -0700 448.2 +++ b/xen/arch/x86/mm.c Wed Aug 24 13:29:21 2005 -0700 448.3 @@ -1449,8 +1449,10 @@ int get_page_type(struct pfn_info *page, 448.4 if ( ((x & PGT_type_mask) != PGT_l2_page_table) || 448.5 ((type & PGT_type_mask) != PGT_l1_page_table) ) 448.6 MEM_LOG("Bad type (saw %" PRtype_info 448.7 - "!= exp %" PRtype_info ") for pfn %lx", 448.8 - x, type, page_to_pfn(page)); 448.9 + "!= exp %" PRtype_info ") " 448.10 + "for mfn %lx (pfn %x)", 448.11 + x, type, page_to_pfn(page), 448.12 + machine_to_phys_mapping[page_to_pfn(page)]); 448.13 return 0; 448.14 } 448.15 else if ( (x & PGT_va_mask) == PGT_va_mutable )