diff -urN 2.4.0ac4/Documentation/Configure.help 2.4.0ac4-lvm/Documentation/Configure.help --- 2.4.0ac4/Documentation/Configure.help Tue Jan 9 01:25:32 2001 +++ 2.4.0ac4-lvm/Documentation/Configure.help Tue Jan 9 01:26:16 2001 @@ -1447,15 +1447,6 @@ want), say M here and read Documentation/modules.txt. The module will be called lvm-mod.o. -Logical Volume Manager /proc file system information -CONFIG_LVM_PROC_FS - If you say Y here, you are able to access overall Logical Volume - Manager, Volume Group, Logical and Physical Volume information in - /proc/lvm. - - To use this option, you have to check, that the "/proc file system - support" (CONFIG_PROC_FS) is enabled too. - Multiple devices driver support CONFIG_BLK_DEV_MD This driver lets you combine several hard disk partitions into one diff -urN 2.4.0ac4/drivers/md/Config.in 2.4.0ac4-lvm/drivers/md/Config.in --- 2.4.0ac4/drivers/md/Config.in Tue Jan 9 01:25:37 2001 +++ 2.4.0ac4-lvm/drivers/md/Config.in Tue Jan 9 01:26:16 2001 @@ -17,6 +17,5 @@ fi dep_tristate ' Logical volume manager (LVM) support' CONFIG_BLK_DEV_LVM $CONFIG_MD -dep_mbool ' LVM information in proc filesystem' CONFIG_LVM_PROC_FS $CONFIG_BLK_DEV_LVM endmenu diff -urN 2.4.0ac4/drivers/md/lvm-snap.c 2.4.0ac4-lvm/drivers/md/lvm-snap.c --- 2.4.0ac4/drivers/md/lvm-snap.c Tue Jan 2 17:41:16 2001 +++ 2.4.0ac4-lvm/drivers/md/lvm-snap.c Tue Jan 9 01:26:17 2001 @@ -214,10 +214,10 @@ memset(lv_COW_table, 0, blksize_snap); for ( ; is < lv_snap->lv_remap_ptr; is++, id++) { /* store new COW_table entry */ - lv_COW_table[id].pv_org_number = LVM_TO_DISK64(lvm_pv_get_number(vg, lv_snap->lv_block_exception[is].rdev_org)); - lv_COW_table[id].pv_org_rsector = LVM_TO_DISK64(lv_snap->lv_block_exception[is].rsector_org); - lv_COW_table[id].pv_snap_number = LVM_TO_DISK64(lvm_pv_get_number(vg, lv_snap->lv_block_exception[is].rdev_new)); - lv_COW_table[id].pv_snap_rsector = LVM_TO_DISK64(lv_snap->lv_block_exception[is].rsector_new); + lv_COW_table[id].pv_org_number = cpu_to_le64(lvm_pv_get_number(vg, lv_snap->lv_block_exception[is].rdev_org)); + lv_COW_table[id].pv_org_rsector = cpu_to_le64(lv_snap->lv_block_exception[is].rsector_org); + lv_COW_table[id].pv_snap_number = cpu_to_le64(lvm_pv_get_number(vg, lv_snap->lv_block_exception[is].rdev_new)); + lv_COW_table[id].pv_snap_rsector = cpu_to_le64(lv_snap->lv_block_exception[is].rsector_new); } } @@ -268,10 +268,10 @@ blocks[0] = (snap_pe_start + COW_table_sector_offset) >> (blksize_snap >> 10); /* store new COW_table entry */ - lv_COW_table[idx_COW_table].pv_org_number = LVM_TO_DISK64(lvm_pv_get_number(vg, lv_snap->lv_block_exception[idx].rdev_org)); - lv_COW_table[idx_COW_table].pv_org_rsector = LVM_TO_DISK64(lv_snap->lv_block_exception[idx].rsector_org); - lv_COW_table[idx_COW_table].pv_snap_number = LVM_TO_DISK64(lvm_pv_get_number(vg, snap_phys_dev)); - lv_COW_table[idx_COW_table].pv_snap_rsector = LVM_TO_DISK64(lv_snap->lv_block_exception[idx].rsector_new); + lv_COW_table[idx_COW_table].pv_org_number = cpu_to_le64(lvm_pv_get_number(vg, lv_snap->lv_block_exception[idx].rdev_org)); + lv_COW_table[idx_COW_table].pv_org_rsector = cpu_to_le64(lv_snap->lv_block_exception[idx].rsector_org); + lv_COW_table[idx_COW_table].pv_snap_number = cpu_to_le64(lvm_pv_get_number(vg, snap_phys_dev)); + lv_COW_table[idx_COW_table].pv_snap_rsector = cpu_to_le64(lv_snap->lv_block_exception[idx].rsector_new); length_tmp = iobuf->length; iobuf->length = blksize_snap; diff -urN 2.4.0ac4/drivers/md/lvm.c 2.4.0ac4-lvm/drivers/md/lvm.c --- 2.4.0ac4/drivers/md/lvm.c Tue Jan 9 01:25:37 2001 +++ 2.4.0ac4-lvm/drivers/md/lvm.c Wed Jan 10 05:36:54 2001 @@ -139,6 +139,7 @@ * lvm_proc_get_global_info() * 02/11/2000 - implemented /proc/lvm/ hierarchy * 07/12/2000 - make sure lvm_make_request_fn returns correct value - 0 or 1 - NeilBrown + * 25/12/2000 - fix procfs #defines - Christoph Hellwig * */ @@ -224,7 +225,7 @@ static int lvm_chr_ioctl(struct inode *, struct file *, uint, ulong); -#if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS +#ifdef CONFIG_PROC_FS int lvm_proc_read_vg_info(char *, char **, off_t, int, int *, void *); int lvm_proc_read_lv_info(char *, char **, off_t, int, int *, void *); int lvm_proc_read_pv_info(char *, char **, off_t, int, int *, void *); @@ -347,7 +348,7 @@ static spinlock_t lvm_lock = SPIN_LOCK_UNLOCKED; static spinlock_t lvm_snapshot_lock = SPIN_LOCK_UNLOCKED; -#if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS +#ifdef CONFIG_PROC_FS static struct proc_dir_entry *lvm_proc_dir = NULL; static struct proc_dir_entry *lvm_proc_vg_subdir = NULL; struct proc_dir_entry *pde = NULL; @@ -433,7 +434,7 @@ &lvm_chr_fops, NULL); #endif -#if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS +#ifdef CONFIG_PROC_FS lvm_proc_dir = create_proc_entry (LVM_DIR, S_IFDIR, &proc_root); if (lvm_proc_dir != NULL) { lvm_proc_vg_subdir = create_proc_entry (LVM_VG_SUBDIR, S_IFDIR, lvm_proc_dir); @@ -521,7 +522,7 @@ blksize_size[MAJOR_NR] = NULL; hardsect_size[MAJOR_NR] = NULL; -#if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS +#ifdef CONFIG_PROC_FS remove_proc_entry(LVM_GLOBAL, lvm_proc_dir); remove_proc_entry(LVM_VG_SUBDIR, lvm_proc_dir); remove_proc_entry(LVM_DIR, &proc_root); @@ -1263,7 +1264,7 @@ } -#if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS +#ifdef CONFIG_PROC_FS /* * Support functions /proc-Filesystem */ @@ -1452,8 +1453,6 @@ else return count; } /* lvm_proc_get_global_info() */ -#endif /* #if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS */ - /* * provide VG information @@ -1530,7 +1529,7 @@ return sz; } - +#endif /* CONFIG_PROC_FS */ /* * block device support function for /usr/src/linux/drivers/block/ll_rw_blk.c @@ -1659,6 +1658,8 @@ if (lv->lv_access & (LV_SNAPSHOT|LV_SNAPSHOT_ORG)) { /* original logical volume */ if (lv->lv_access & LV_SNAPSHOT_ORG) { + /* Serializes the access to the lv_snapshot_next list */ + down(&lv->lv_snapshot_sem); if (rw == WRITE || rw == WRITEA) { lv_t *lv_ptr; @@ -1669,7 +1670,8 @@ lv_ptr = lv_ptr->lv_snapshot_next) { /* Check for inactive snapshot */ if (!(lv_ptr->lv_status & LV_ACTIVE)) continue; - down(&lv->lv_snapshot_org->lv_snapshot_sem); + /* Serializes the COW with the accesses to the snapshot device */ + down(&lv_ptr->lv_snapshot_sem); /* do we still have exception storage for this snapshot free? */ if (lv_ptr->lv_block_exception != NULL) { rdev_sav = rdev_tmp; @@ -1690,9 +1692,10 @@ rdev_tmp = rdev_sav; rsector_tmp = rsector_sav; } - up(&lv->lv_snapshot_org->lv_snapshot_sem); + up(&lv_ptr->lv_snapshot_sem); } } + up(&lv->lv_snapshot_sem); } else { /* remap snapshot logical volume */ down(&lv->lv_snapshot_sem); @@ -1989,7 +1992,7 @@ &lvm_chr_fops, NULL); #endif -#if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS +#ifdef CONFIG_PROC_FS lvm_do_create_proc_entry_of_vg ( vg_ptr); #endif @@ -2021,21 +2024,11 @@ for (p = 0; p < vg_ptr->pv_max; p++) { if ( ( pv_ptr = vg_ptr->pv[p]) == NULL) { ret = lvm_do_pv_create(arg, vg_ptr, p); -#if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS - lvm_do_create_proc_entry_of_pv ( vg_ptr, pv_ptr); -#endif if ( ret != 0) return ret; - - /* We don't need the PE list - in kernel space like LVs pe_t list */ - pv_ptr->pe = NULL; - vg_ptr->pv_cur++; - vg_ptr->pv_act++; - vg_ptr->pe_total += - pv_ptr->pe_total; -#ifdef LVM_GET_INODE - /* insert a dummy inode for fs_may_mount */ - pv_ptr->inode = lvm_get_inode(pv_ptr->pv_dev); + pv_ptr = vg_ptr->pv[p] ; + vg_ptr->pe_total += pv_ptr->pe_total; +#ifdef CONFIG_PROC_FS + lvm_do_create_proc_entry_of_pv ( vg_ptr, pv_ptr); #endif return 0; } @@ -2062,10 +2055,6 @@ strcmp(pv_ptr->pv_name, pv_name) == 0) { if (pv_ptr->lv_cur > 0) return -EPERM; - vg_ptr->pe_total -= - pv_ptr->pe_total; - vg_ptr->pv_cur--; - vg_ptr->pv_act--; lvm_do_pv_remove(vg_ptr, p); /* Make PV pointer array contiguous */ for (; p < vg_ptr->pv_max - 1; p++) @@ -2093,7 +2082,7 @@ if (copy_from_user(vg_name, arg, sizeof(vg_name)) != 0) return -EFAULT; -#if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS +#ifdef CONFIG_PROC_FS lvm_do_remove_proc_entry_of_vg ( vg_ptr); #endif @@ -2117,7 +2106,7 @@ strncpy(pv_ptr->vg_name, vg_name, NAME_LEN); } -#if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS +#ifdef CONFIG_PROC_FS lvm_do_create_proc_entry_of_vg ( vg_ptr); #endif @@ -2181,7 +2170,7 @@ devfs_unregister (vg_devfs_handle[vg_ptr->vg_number]); #endif -#if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS +#ifdef CONFIG_PROC_FS lvm_do_remove_proc_entry_of_vg ( vg_ptr); #endif @@ -2239,7 +2228,7 @@ static int lvm_do_pv_remove(vg_t *vg_ptr, ulong p) { pv_t *pv_ptr = vg_ptr->pv[p]; -#if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS +#ifdef CONFIG_PROC_FS lvm_do_remove_proc_entry_of_pv ( vg_ptr, pv_ptr); #endif vg_ptr->pe_total -= @@ -2374,18 +2363,10 @@ lv_ptr->lv_snapshot_minor = 0; lv_ptr->lv_snapshot_org = lv_ptr; - lv_ptr->lv_snapshot_prev = NULL; - /* walk thrugh the snapshot list */ - while (lv_ptr->lv_snapshot_next != NULL) - lv_ptr = lv_ptr->lv_snapshot_next; - /* now lv_ptr points to the last existing snapshot in the chain */ - vg_ptr->lv[l]->lv_snapshot_prev = lv_ptr; /* our new one now back points to the previous last in the chain which can be the original logical volume */ lv_ptr = vg_ptr->lv[l]; /* now lv_ptr points to our new last snapshot logical volume */ - lv_ptr->lv_snapshot_org = lv_ptr->lv_snapshot_prev->lv_snapshot_org; - lv_ptr->lv_snapshot_next = NULL; lv_ptr->lv_current_pe = lv_ptr->lv_snapshot_org->lv_current_pe; lv_ptr->lv_allocated_le = lv_ptr->lv_snapshot_org->lv_allocated_le; lv_ptr->lv_current_le = lv_ptr->lv_snapshot_org->lv_current_le; @@ -2444,22 +2425,27 @@ } #endif -#if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS +#ifdef CONFIG_PROC_FS lvm_do_create_proc_entry_of_lv ( vg_ptr, lv_ptr); #endif /* optionally add our new snapshot LV */ if (lv_ptr->lv_access & LV_SNAPSHOT) { + lv_t * org = lv_ptr->lv_snapshot_org, * last; /* sync the original logical volume */ - fsync_dev(lv_ptr->lv_snapshot_org->lv_dev); + fsync_dev(org->lv_dev); #ifdef LVM_VFS_ENHANCEMENT /* VFS function call to sync and lock the filesystem */ - fsync_dev_lockfs(lv_ptr->lv_snapshot_org->lv_dev); + fsync_dev_lockfs(org->lv_dev); #endif - lv_ptr->lv_snapshot_org->lv_access |= LV_SNAPSHOT_ORG; - lv_ptr->lv_access &= ~LV_SNAPSHOT_ORG; - /* put ourselve into the chain */ - lv_ptr->lv_snapshot_prev->lv_snapshot_next = lv_ptr; + down(&org->lv_snapshot_sem); + org->lv_access |= LV_SNAPSHOT_ORG; + lv_ptr->lv_access &= ~LV_SNAPSHOT_ORG; /* this can only hide an userspace bug */ + /* Link in the list of snapshot volumes */ + for (last = org; last->lv_snapshot_next; last = last->lv_snapshot_next); + lv_ptr->lv_snapshot_prev = last; + last->lv_snapshot_next = lv_ptr; + up(&org->lv_snapshot_sem); } /* activate the logical volume */ @@ -2515,6 +2501,28 @@ lv_ptr->lv_snapshot_next != NULL) return -EPERM; + if (lv_ptr->lv_access & LV_SNAPSHOT) { + /* + * Atomically make the the snapshot invisible + * to the original lv before playing with it. + */ + lv_t * org = lv_ptr->lv_snapshot_org; + down(&org->lv_snapshot_sem); + + /* remove this snapshot logical volume from the chain */ + lv_ptr->lv_snapshot_prev->lv_snapshot_next = lv_ptr->lv_snapshot_next; + if (lv_ptr->lv_snapshot_next != NULL) { + lv_ptr->lv_snapshot_next->lv_snapshot_prev = + lv_ptr->lv_snapshot_prev; + } + up(&org->lv_snapshot_sem); + + /* no more snapshots? */ + if (!org->lv_snapshot_next) + org->lv_access &= ~LV_SNAPSHOT_ORG; + lvm_snapshot_release(lv_ptr); + } + lv_ptr->lv_status |= LV_SPINDOWN; /* sync the buffers */ @@ -2548,25 +2556,13 @@ } } vfree(lv_ptr->lv_current_pe); - /* LV_SNAPSHOT */ - } else { - /* remove this snapshot logical volume from the chain */ - lv_ptr->lv_snapshot_prev->lv_snapshot_next = lv_ptr->lv_snapshot_next; - if (lv_ptr->lv_snapshot_next != NULL) { - lv_ptr->lv_snapshot_next->lv_snapshot_prev = - lv_ptr->lv_snapshot_prev; - } - /* no more snapshots? */ - if (lv_ptr->lv_snapshot_org->lv_snapshot_next == NULL) - lv_ptr->lv_snapshot_org->lv_access &= ~LV_SNAPSHOT_ORG; - lvm_snapshot_release(lv_ptr); } #ifdef CONFIG_DEVFS_FS devfs_unregister(lv_devfs_handle[lv_ptr->lv_number]); #endif -#if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS +#ifdef CONFIG_PROC_FS lvm_do_remove_proc_entry_of_lv ( vg_ptr, lv_ptr); #endif @@ -2916,13 +2912,13 @@ if ( (lv_ptr = vg_ptr->lv[l]) == NULL) continue; if (lv_ptr->lv_dev == lv->lv_dev) { -#if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS +#ifdef CONFIG_PROC_FS lvm_do_remove_proc_entry_of_lv ( vg_ptr, lv_ptr); #endif strncpy(lv_ptr->lv_name, lv_req->lv_name, NAME_LEN); -#if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS +#ifdef CONFIG_PROC_FS lvm_do_create_proc_entry_of_lv ( vg_ptr, lv_ptr); #endif break; @@ -3004,9 +3000,7 @@ } /* lvm_do_pv_status() */ -#if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS - - +#ifdef CONFIG_PROC_FS /* * create a /proc entry for a logical volume */ @@ -3135,8 +3129,7 @@ remove_proc_entry(vg_ptr->vg_name, lvm_proc_vg_subdir); } } -#endif - +#endif /* CONFIG_PROC_FS */ /* * support function initialize gendisk variables diff -urN 2.4.0ac4/include/linux/lvm.h 2.4.0ac4-lvm/include/linux/lvm.h --- 2.4.0ac4/include/linux/lvm.h Mon Jan 8 06:33:52 2001 +++ 2.4.0ac4-lvm/include/linux/lvm.h Tue Jan 9 01:26:17 2001 @@ -57,6 +57,8 @@ * 26/06/2000 - implemented snapshot persistency and resizing support * 02/11/2000 - added hash table size member to lv structure * 12/11/2000 - removed unneeded timestamp definitions + * 24/12/2000 - removed LVM_TO_{CORE,DISK}*, use cpu_{from, to}_le* + * instead - Christoph Hellwig * */ @@ -68,7 +70,6 @@ #include #include -#include /* * preprocessor definitions @@ -324,51 +325,6 @@ COW_table_entries_per_PE = LVM_GET_COW_TABLE_CHUNKS_PER_PE(vg, lv); \ COW_table_chunks_per_PE = ( COW_table_entries_per_PE * sizeof(lv_COW_table_disk_t) / SECTOR_SIZE + lv->lv_chunk_size - 1) / lv->lv_chunk_size; \ COW_table_entries_per_PE - COW_table_chunks_per_PE;}) - - -/* to disk and to core data conversion macros */ -#if __BYTE_ORDER == __BIG_ENDIAN - -#define LVM_TO_CORE16(x) ( \ - ((uint16_t)((((uint16_t)(x) & 0x00FFU) << 8) | \ - (((uint16_t)(x) & 0xFF00U) >> 8)))) - -#define LVM_TO_DISK16(x) LVM_TO_CORE16(x) - -#define LVM_TO_CORE32(x) ( \ - ((uint32_t)((((uint32_t)(x) & 0x000000FFU) << 24) | \ - (((uint32_t)(x) & 0x0000FF00U) << 8))) \ - (((uint32_t)(x) & 0x00FF0000U) >> 8))) \ - (((uint32_t)(x) & 0xFF000000U) >> 24)))) - -#define LVM_TO_DISK32(x) LVM_TO_CORE32(x) - -#define LVM_TO_CORE64(x) \ - ((uint64_t)((((uint64_t)(x) & 0x00000000000000FFULL) << 56) | \ - (((uint64_t)(x) & 0x000000000000FF00ULL) << 40) | \ - (((uint64_t)(x) & 0x0000000000FF0000ULL) << 24) | \ - (((uint64_t)(x) & 0x00000000FF000000ULL) << 8) | \ - (((uint64_t)(x) & 0x000000FF00000000ULL) >> 8) | \ - (((uint64_t)(x) & 0x0000FF0000000000ULL) >> 24) | \ - (((uint64_t)(x) & 0x00FF000000000000ULL) >> 40) | \ - (((uint64_t)(x) & 0xFF00000000000000ULL) >> 56))) - -#define LVM_TO_DISK64(x) LVM_TO_CORE64(x) - -#elif __BYTE_ORDER == __LITTLE_ENDIAN - -#define LVM_TO_CORE16(x) x -#define LVM_TO_DISK16(x) x -#define LVM_TO_CORE32(x) x -#define LVM_TO_DISK32(x) x -#define LVM_TO_CORE64(x) x -#define LVM_TO_DISK64(x) x - -#else - -#error "__BYTE_ORDER must be defined as __LITTLE_ENDIAN or __BIG_ENDIAN" - -#endif /* #if __BYTE_ORDER == __BIG_ENDIAN */ /*