diff options
author | davem <davem> | 2001-12-17 03:52:35 +0000 |
---|---|---|
committer | davem <davem> | 2001-12-17 03:52:35 +0000 |
commit | 3adba7c7862ac06d874ca5e72deea69035afe46d (patch) | |
tree | c1974e1cb083c62b94b2c99b0efe6a145e98413b | |
parent | c6858b1a2d38255db140bb36f06025c4e9a73db8 (diff) | |
download | netdev-vger-cvs-3adba7c7862ac06d874ca5e72deea69035afe46d.tar.gz |
Merge mainline to 2.5.1-final.
149 files changed, 1187 insertions, 1692 deletions
@@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 5 SUBLEVEL = 1 -EXTRAVERSION =-pre11 +EXTRAVERSION = KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) diff --git a/arch/m68k/kernel/setup.c b/arch/m68k/kernel/setup.c index 86007efb1..57a954d7e 100644 --- a/arch/m68k/kernel/setup.c +++ b/arch/m68k/kernel/setup.c @@ -93,7 +93,6 @@ void (*mach_power_off)( void ) = NULL; long mach_max_dma_address = 0x00ffffff; /* default set to the lower 16MB */ #if defined(CONFIG_AMIGA_FLOPPY) || defined(CONFIG_ATARI_FLOPPY) void (*mach_floppy_setup) (char *, int *) __initdata = NULL; -void (*mach_floppy_eject) (void) = NULL; #endif #ifdef CONFIG_HEARTBEAT void (*mach_heartbeat) (int) = NULL; @@ -514,11 +513,6 @@ void __init floppy_setup(char *str, int *ints) mach_floppy_setup (str, ints); } -void floppy_eject(void) -{ - if (mach_floppy_eject) - mach_floppy_eject(); -} #endif /* for "kbd-reset" cmdline param */ diff --git a/arch/m68k/q40/config.c b/arch/m68k/q40/config.c index 23690901c..4989e67bc 100644 --- a/arch/m68k/q40/config.c +++ b/arch/m68k/q40/config.c @@ -36,7 +36,6 @@ #include <asm/q40_master.h> #include <asm/keyboard.h> -extern void floppy_eject(void); extern void floppy_setup(char *str, int *ints); extern int q40kbd_translate(unsigned char scancode, unsigned char *keycode, diff --git a/arch/ppc/kernel/apus_setup.c b/arch/ppc/kernel/apus_setup.c index bdbc452bc..c3fe77cde 100644 --- a/arch/ppc/kernel/apus_setup.c +++ b/arch/ppc/kernel/apus_setup.c @@ -106,7 +106,6 @@ void (*mach_reset)( void ); long mach_max_dma_address = 0x00ffffff; /* default set to the lower 16MB */ #if defined(CONFIG_AMIGA_FLOPPY) void (*mach_floppy_setup) (char *, int *) __initdata = NULL; -void (*mach_floppy_eject) (void) = NULL; #endif #ifdef CONFIG_HEARTBEAT void (*mach_heartbeat) (int) = NULL; @@ -404,12 +403,6 @@ void floppy_setup(char *str, int *ints) if (mach_floppy_setup) mach_floppy_setup (str, ints); } - -void floppy_eject(void) -{ - if (mach_floppy_eject) - mach_floppy_eject(); -} #endif /*********************************************************** MEMORY */ diff --git a/drivers/acorn/block/fd1772.c b/drivers/acorn/block/fd1772.c index d9cf8b505..1667797e2 100644 --- a/drivers/acorn/block/fd1772.c +++ b/drivers/acorn/block/fd1772.c @@ -1620,7 +1620,3 @@ int fd1772_init(void) return 0; } - -void floppy_eject(void) -{ -} diff --git a/drivers/block/acsi.c b/drivers/block/acsi.c index 89d350be9..28e5ae8e0 100644 --- a/drivers/block/acsi.c +++ b/drivers/block/acsi.c @@ -253,7 +253,7 @@ static int CurrentNReq; static int CurrentNSect; static char *CurrentBuffer; -static spinlock_t acsi_lock; +static spinlock_t acsi_lock = SPIN_LOCK_UNLOCKED; #define SET_TIMER() mod_timer(&acsi_timer, jiffies + ACSI_TIMEOUT) diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c index 7f357157e..c2e353b88 100644 --- a/drivers/block/amiflop.c +++ b/drivers/block/amiflop.c @@ -174,7 +174,7 @@ static int writepending; static int writefromint; static char *raw_buf; -static spinlock_t amiflop_lock; +static spinlock_t amiflop_lock = SPIN_LOCK_UNLOCKED; #define RAW_BUF_SIZE 30000 /* size of raw disk data */ diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c index 19997245e..1386f3eba 100644 --- a/drivers/block/ataflop.c +++ b/drivers/block/ataflop.c @@ -156,7 +156,7 @@ static int StartDiskType[] = { static int DriveType = TYPE_HD; -static spinlock_t ataflop_lock; +static spinlock_t ataflop_lock = SPIN_LOCK_UNLOCKED; /* Array for translating minors into disk formats */ static struct { diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index feaf7217f..b038dde8b 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -1866,6 +1866,7 @@ static int __init cciss_init_one(struct pci_dev *pdev, q = BLK_DEFAULT_QUEUE(MAJOR_NR + i); q->queuedata = hba[i]; + spin_lock_init(&hba[i]->lock); blk_init_queue(q, do_cciss_request, &hba[i]->lock); blk_queue_bounce_limit(q, hba[i]->pdev->dma_mask); diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c index 2aa1d0365..5f2298ba9 100644 --- a/drivers/block/cpqarray.c +++ b/drivers/block/cpqarray.c @@ -467,6 +467,7 @@ int __init cpqarray_init(void) q = BLK_DEFAULT_QUEUE(MAJOR_NR + i); q->queuedata = hba[i]; + spin_lock_init(&hba[i]->lock); blk_init_queue(q, do_ida_request, &hba[i]->lock); blk_queue_bounce_limit(q, hba[i]->pci_dev->dma_mask); diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 800c5b0ae..2fcdcc59a 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -204,7 +204,7 @@ static int use_virtual_dma; * record each buffers capabilities */ -static spinlock_t floppy_lock; +static spinlock_t floppy_lock = SPIN_LOCK_UNLOCKED; static unsigned short virtual_dma_port=0x3f0; void floppy_interrupt(int irq, void *dev_id, struct pt_regs * regs); @@ -4479,23 +4479,4 @@ MODULE_LICENSE("GPL"); __setup ("floppy=", floppy_setup); module_init(floppy_init) - -/* eject the boot floppy (if we need the drive for a different root floppy) */ -/* This should only be called at boot time when we're sure that there's no - * resource contention. */ -void floppy_eject(void) -{ - int dummy; - if (have_no_fdc) - return; - if(floppy_grab_irq_and_dma()==0) - { - lock_fdc(MAXTIMEOUT,0); - dummy=fd_eject(0); - process_fd_request(); - floppy_release_irq_and_dma(); - } -} #endif - -EXPORT_NO_SYMBOLS; diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c index f8febd812..e5c93889d 100644 --- a/drivers/block/ll_rw_blk.c +++ b/drivers/block/ll_rw_blk.c @@ -172,6 +172,18 @@ void blk_queue_bounce_limit(request_queue_t *q, u64 dma_addr) static request_queue_t *last_q; /* + * set appropriate bounce gfp mask -- unfortunately we don't have a + * full 4GB zone, so we have to resort to low memory for any bounces. + * ISA has its own < 16MB zone. + */ + if (dma_addr == BLK_BOUNCE_ISA) { + init_emergency_isa_pool(); + q->bounce_gfp = GFP_NOIO | GFP_DMA; + printk("isa pfn %lu, max low %lu, max %lu\n", bounce_pfn, blk_max_low_pfn, blk_max_pfn); + } else + q->bounce_gfp = GFP_NOHIGHIO; + + /* * keep this for debugging for now... */ if (dma_addr != BLK_BOUNCE_HIGH && q != last_q) { diff --git a/drivers/block/loop.c b/drivers/block/loop.c index b5c18e74b..ec601cc07 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -621,10 +621,6 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file, kdev_t dev, if (S_ISBLK(inode->i_mode)) { lo_device = inode->i_rdev; - if (lo_device == dev) { - error = -EBUSY; - goto out; - } } else if (S_ISREG(inode->i_mode)) { struct address_space_operations *aops = inode->i_mapping->a_ops; /* diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index c16b6163a..38b2514d7 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -62,7 +62,7 @@ static u64 nbd_bytesizes[MAX_NBD]; static struct nbd_device nbd_dev[MAX_NBD]; static devfs_handle_t devfs_handle; -static spinlock_t nbd_lock; +static spinlock_t nbd_lock = SPIN_LOCK_UNLOCKED; #define DEBUG( s ) /* #define DEBUG( s ) printk( s ) diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c index 48199cdad..8e1374c18 100644 --- a/drivers/block/paride/pd.c +++ b/drivers/block/paride/pd.c @@ -166,7 +166,7 @@ static int pd_drive_count; #include <asm/uaccess.h> -static spinlock_t pd_lock; +static spinlock_t pd_lock = SPIN_LOCK_UNLOCKED; #ifndef MODULE diff --git a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c index cb4454267..c83901c70 100644 --- a/drivers/block/paride/pf.c +++ b/drivers/block/paride/pf.c @@ -684,8 +684,7 @@ static void xs( char *buf, char *targ, int offs, int len ) for (k=0;k<len;k++) if((buf[k+offs]!=0x20)||(buf[k+offs]!=l)) l=targ[j++]=buf[k+offs]; - if (l==0x20) j--; - targ[j]=0; + if (l==0x20) j--; targ[j]=0; } static int xl( char *buf, int offs ) diff --git a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c index 19b715eb8..bf680c022 100644 --- a/drivers/block/paride/pg.c +++ b/drivers/block/paride/pg.c @@ -491,8 +491,7 @@ static void xs( char *buf, char *targ, int offs, int len ) for (k=0;k<len;k++) if((buf[k+offs]!=0x20)||(buf[k+offs]!=l)) l=targ[j++]=buf[k+offs]; - if (l==0x20) j--; - targ[j]=0; + if (l==0x20) j--; targ[j]=0; } static int pg_identify( int unit, int log ) diff --git a/drivers/block/paride/pseudo.h b/drivers/block/paride/pseudo.h index 25cde3063..31cf68d5c 100644 --- a/drivers/block/paride/pseudo.h +++ b/drivers/block/paride/pseudo.h @@ -102,7 +102,7 @@ static void ps_tq_int( void *data ) spin_unlock_irqrestore(&ps_spinlock,flags); return; } - if (!ps_ready || ps_ready() || time_after_eq(jiffies, ps_timeout)) { + if (!ps_ready || ps_ready() || (jiffies >= ps_timeout)) { ps_continuation = NULL; spin_unlock_irqrestore(&ps_spinlock,flags); con(); @@ -131,7 +131,7 @@ static void ps_timer_int( unsigned long data) spin_unlock_irqrestore(&ps_spinlock,flags); return; } - if (!ps_ready || ps_ready() || time_after_eq(jiffies, ps_timeout)) { + if (!ps_ready || ps_ready() || (jiffies >= ps_timeout)) { ps_continuation = NULL; spin_unlock_irqrestore(&ps_spinlock,flags); con(); diff --git a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c index b0c43d9fe..725960050 100644 --- a/drivers/block/paride/pt.c +++ b/drivers/block/paride/pt.c @@ -577,8 +577,7 @@ static void xs( char *buf, char *targ, int offs, int len ) for (k=0;k<len;k++) if((buf[k+offs]!=0x20)||(buf[k+offs]!=l)) l=targ[j++]=buf[k+offs]; - if (l==0x20) j--; - targ[j]=0; + if (l==0x20) j--; targ[j]=0; } static int xn( char *buf, int offs, int size ) diff --git a/drivers/block/ps2esdi.c b/drivers/block/ps2esdi.c index 81da0161d..dec02f0f8 100644 --- a/drivers/block/ps2esdi.c +++ b/drivers/block/ps2esdi.c @@ -128,7 +128,7 @@ static int intg_esdi = 0; /* If integrated adapter */ struct ps2esdi_i_struct { unsigned int head, sect, cyl, wpcom, lzone, ctl; }; -static spinlock_t ps2esdi_lock; +static spinlock_t ps2esdi_lock = SPIN_LOCK_UNLOCKED; #if 0 #if 0 /* try both - I don't know which one is better... UB */ diff --git a/drivers/block/rd.c b/drivers/block/rd.c index 4cf2978d0..c6fb55df1 100644 --- a/drivers/block/rd.c +++ b/drivers/block/rd.c @@ -99,7 +99,7 @@ static struct block_device *rd_bdev[NUM_RAMDISKS];/* Protected device data */ */ int rd_size = CONFIG_BLK_DEV_RAM_SIZE; /* Size of the RAM disks */ /* - * It would be very desirable to have a soft-blocksize (that in the case + * It would be very desiderable to have a soft-blocksize (that in the case * of the ramdisk driver is also the hardblocksize ;) of PAGE_SIZE because * doing that we'll achieve a far better MM footprint. Using a rd_blocksize of * BLOCK_SIZE in the worst case we'll make PAGE_SIZE/BLOCK_SIZE buffer-pages diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c index 56081fc08..ad3ead361 100644 --- a/drivers/block/swim3.c +++ b/drivers/block/swim3.c @@ -203,7 +203,7 @@ struct floppy_state { static struct floppy_state floppy_states[MAX_FLOPPIES]; static int floppy_count = 0; -static spinlock_t swim3_lock; +static spinlock_t swim3_lock = SPIN_LOCK_UNLOCKED; static unsigned short write_preamble[] = { 0x4e4e, 0x4e4e, 0x4e4e, 0x4e4e, 0x4e4e, /* gap field */ @@ -808,16 +808,6 @@ static int fd_eject(struct floppy_state *fs) return err; } -int swim3_fd_eject(int devnum) -{ - if (devnum >= floppy_count) - return -ENODEV; - /* Do not check this - this function should ONLY be called early - * in the boot process! */ - /* if (floppy_states[devnum].ref_count != 1) return -EBUSY; */ - return fd_eject(&floppy_states[devnum]); -} - static struct floppy_struct floppy_type = { 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,NULL }; /* 7 1.44MB 3.5" */ diff --git a/drivers/block/swim_iop.c b/drivers/block/swim_iop.c index 8c95cabd1..0fbe21e39 100644 --- a/drivers/block/swim_iop.c +++ b/drivers/block/swim_iop.c @@ -84,7 +84,7 @@ static struct floppy_state floppy_states[MAX_FLOPPIES]; static int floppy_blocksizes[2] = {512,512}; static int floppy_sizes[2] = {2880,2880}; -static spinlock_t swim_iop_lock; +static spinlock_t swim_iop_lock = SPIN_LOCK_UNLOCKED; static char *drive_names[7] = { "not installed", /* DRV_NONE */ diff --git a/drivers/block/xd.c b/drivers/block/xd.c index ae34bf493..55587b464 100644 --- a/drivers/block/xd.c +++ b/drivers/block/xd.c @@ -122,7 +122,7 @@ static struct hd_struct xd_struct[XD_MAXDRIVES << 6]; static int xd_sizes[XD_MAXDRIVES << 6], xd_access[XD_MAXDRIVES]; static int xd_blocksizes[XD_MAXDRIVES << 6]; -static spinlock_t xd_lock; +static spinlock_t xd_lock = SPIN_LOCK_UNLOCKED; extern struct block_device_operations xd_fops; diff --git a/drivers/block/z2ram.c b/drivers/block/z2ram.c index e050e31ce..f7d35d730 100644 --- a/drivers/block/z2ram.c +++ b/drivers/block/z2ram.c @@ -68,6 +68,8 @@ static int chip_count = 0; static int list_count = 0; static int current_device = -1; +static spinlock_t z2ram_lock = SPIN_LOCK_UNLOCKED; + static void do_z2_request( request_queue_t * q ) { @@ -364,7 +366,7 @@ z2_init( void ) } } - blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST); + blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUES, &z2ram_lock); blksize_size[ MAJOR_NR ] = z2_blocksizes; blk_size[ MAJOR_NR ] = z2_sizes; diff --git a/drivers/ide/hd.c b/drivers/ide/hd.c index 868305afd..08485cf66 100644 --- a/drivers/ide/hd.c +++ b/drivers/ide/hd.c @@ -62,7 +62,7 @@ #define HD_IRQ IRQ_HARDDISK #endif -static spinlock_t hd_lock; +static spinlock_t hd_lock = SPIN_LOCK_UNLOCKED; static int revalidate_hddisk(kdev_t, int); diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index c1b19e1d9..c4eb0a4a3 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -3686,6 +3686,7 @@ EXPORT_SYMBOL(ide_spin_wait_hwgroup); */ devfs_handle_t ide_devfs_handle; +EXPORT_SYMBOL(ide_lock); EXPORT_SYMBOL(ide_probe); EXPORT_SYMBOL(drive_is_flashcard); EXPORT_SYMBOL(ide_timer_expiry); @@ -3718,6 +3719,7 @@ EXPORT_SYMBOL(ide_do_drive_cmd); EXPORT_SYMBOL(ide_end_drive_cmd); EXPORT_SYMBOL(ide_end_request); EXPORT_SYMBOL(__ide_end_request); +EXPORT_SYMBOL(ide_revalidate_drive); EXPORT_SYMBOL(ide_revalidate_disk); EXPORT_SYMBOL(ide_cmd); EXPORT_SYMBOL(ide_wait_cmd); diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index f3528a29e..2e51889ac 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile @@ -135,7 +135,7 @@ obj-$(CONFIG_CHR_DEV_SG) += sg.o list-multi := scsi_mod.o sd_mod.o sr_mod.o initio.o a100u2w.o cpqfc.o scsi_mod-objs := scsi.o hosts.o scsi_ioctl.o constants.o scsicam.o \ scsi_proc.o scsi_error.o scsi_queue.o scsi_lib.o \ - scsi_merge.o scsi_dma.o scsi_scan.o scsi_syms.o + scsi_merge.o scsi_scan.o scsi_syms.o sd_mod-objs := sd.o sr_mod-objs := sr.o sr_ioctl.o sr_vendor.o initio-objs := ini9100u.o i91uscsi.o diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index a33868d94..cf32a8a3a 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -130,7 +130,8 @@ scsi_unregister(struct Scsi_Host * sh){ * pain to reverse this, so we try to avoid it */ extern int blk_nohighio; -struct Scsi_Host * scsi_register(Scsi_Host_Template * tpnt, int j){ +struct Scsi_Host * scsi_register(Scsi_Host_Template * tpnt, int j) +{ struct Scsi_Host * retval, *shpnt, *o_shp; Scsi_Host_Name *shn, *shn2; int flag_new = 1; diff --git a/drivers/scsi/hosts.h b/drivers/scsi/hosts.h index 08f3ea280..9045cc4cb 100644 --- a/drivers/scsi/hosts.h +++ b/drivers/scsi/hosts.h @@ -334,7 +334,6 @@ struct Scsi_Host int resetting; /* if set, it means that last_reset is a valid value */ unsigned long last_reset; - /* * These three parameters can be used to allow for wide scsi, * and for host adapters that support multiple busses diff --git a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c index 4d4ac2e12..ce2e2e090 100644 --- a/drivers/scsi/ncr53c8xx.c +++ b/drivers/scsi/ncr53c8xx.c @@ -8132,7 +8132,7 @@ static int ncr_scatter(ncb_p np, ccb_p cp, Scsi_Cmnd *cmd) use_sg = map_scsi_sg_data(np, cmd); if (use_sg > MAX_SCATTER) { - unmap_scsi_sg_data(np, cmd); + unmap_scsi_data(np, cmd); return -1; } data = &data[MAX_SCATTER - use_sg]; diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 0710bf2f5..98a478083 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -55,6 +55,7 @@ #include <linux/init.h> #include <linux/smp_lock.h> #include <linux/completion.h> +#include <linux/mempool.h> #define __KERNEL_SYSCALLS__ @@ -83,6 +84,18 @@ static int scsi_proc_info(char *buffer, char **start, off_t offset, int length); static void scsi_dump_status(int level); #endif +#define SG_MEMPOOL_NR 5 +#define SG_MEMPOOL_SIZE 32 + +struct scsi_host_sg_pool { + int size; + kmem_cache_t *slab; + mempool_t *pool; +}; + +static const int scsi_host_sg_pool_sizes[SG_MEMPOOL_NR] = { 8, 16, 32, 64, MAX_PHYS_SEGMENTS }; +struct scsi_host_sg_pool scsi_sg_pools[SG_MEMPOOL_NR]; + /* static const char RCSid[] = "$Header: /vger/u4/cvs/linux/drivers/scsi/scsi.c,v 1.38 1997/01/19 23:07:18 davem Exp $"; */ @@ -1954,13 +1967,6 @@ static int scsi_register_host(Scsi_Host_Template * tpnt) } } - /* - * Now that we have all of the devices, resize the DMA pool, - * as required. */ - if (!out_of_space) - scsi_resize_dma_pool(); - - /* This does any final handling that is required. */ for (sdtpnt = scsi_devicelist; sdtpnt; sdtpnt = sdtpnt->next) { if (sdtpnt->finish && sdtpnt->nr_dev) { @@ -2159,14 +2165,6 @@ static int scsi_unregister_host(Scsi_Host_Template * tpnt) tpnt->present--; } - /* - * If there are absolutely no more hosts left, it is safe - * to completely nuke the DMA pool. The resize operation will - * do the right thing and free everything. - */ - if (!scsi_hosts) - scsi_resize_dma_pool(); - if (pcount0 != next_scsi_host) printk(KERN_INFO "scsi : %d host%s left.\n", next_scsi_host, (next_scsi_host == 1) ? "" : "s"); @@ -2267,8 +2265,6 @@ static int scsi_register_device_module(struct Scsi_Device_Template *tpnt) */ if (tpnt->finish && tpnt->nr_dev) (*tpnt->finish) (); - if (!out_of_space) - scsi_resize_dma_pool(); MOD_INC_USE_COUNT; if (out_of_space) { @@ -2534,16 +2530,81 @@ int __init scsi_setup(char *str) __setup("scsihosts=", scsi_setup); #endif +static void *scsi_pool_alloc(int gfp_mask, void *data) +{ + return kmem_cache_alloc(data, gfp_mask); +} + +static void scsi_pool_free(void *ptr, void *data) +{ + kmem_cache_free(data, ptr); +} + +struct scatterlist *scsi_alloc_sgtable(Scsi_Cmnd *SCpnt, int gfp_mask) +{ + struct scsi_host_sg_pool *sgp; + struct scatterlist *sgl; + + BUG_ON(!SCpnt->use_sg); + + switch (SCpnt->use_sg) { + case 1 ... 8 : SCpnt->sglist_len = 0; break; + case 9 ... 16 : SCpnt->sglist_len = 1; break; + case 17 ... 32 : SCpnt->sglist_len = 2; break; + case 33 ... 64 : SCpnt->sglist_len = 3; break; + case 65 ... MAX_PHYS_SEGMENTS : SCpnt->sglist_len = 4; break; + default: return NULL; + } + + sgp = scsi_sg_pools + SCpnt->sglist_len; + + sgl = mempool_alloc(sgp->pool, gfp_mask); + if (sgl) { + memset(sgl, 0, sgp->size); + return sgl; + } + + return sgl; +} + +void scsi_free_sgtable(struct scatterlist *sgl, int index) +{ + struct scsi_host_sg_pool *sgp = scsi_sg_pools + index; + + if (unlikely(index > SG_MEMPOOL_NR)) { + printk("scsi_free_sgtable: mempool %d\n", index); + BUG(); + } + + mempool_free(sgl, sgp->pool); +} + static int __init init_scsi(void) { struct proc_dir_entry *generic; + char name[16]; + int i; printk(KERN_INFO "SCSI subsystem driver " REVISION "\n"); - if( scsi_init_minimal_dma_pool() != 0 ) - { - return 1; - } + /* + * setup sg memory pools + */ + for (i = 0; i < SG_MEMPOOL_NR; i++) { + struct scsi_host_sg_pool *sgp = scsi_sg_pools + i; + int size = scsi_host_sg_pool_sizes[i] * sizeof(struct scatterlist); + + snprintf(name, sizeof(name) - 1, "sgpool-%d", scsi_host_sg_pool_sizes[i]); + sgp->slab = kmem_cache_create(name, size, 0, SLAB_HWCACHE_ALIGN, NULL, NULL); + if (!sgp->slab) + panic("SCSI: can't init sg slab\n"); + + sgp->pool = mempool_create(SG_MEMPOOL_SIZE, scsi_pool_alloc, scsi_pool_free, sgp->slab); + if (!sgp->pool) + panic("SCSI: can't init sg mempool\n"); + + sgp->size = size; + } /* * This makes /proc/scsi and /proc/scsi/scsi visible. @@ -2579,6 +2640,7 @@ static int __init init_scsi(void) static void __exit exit_scsi(void) { Scsi_Host_Name *shn, *shn2 = NULL; + int i; remove_bh(SCSI_BH); @@ -2599,11 +2661,13 @@ static void __exit exit_scsi(void) remove_proc_entry ("scsi", 0); #endif - /* - * Free up the DMA pool. - */ - scsi_resize_dma_pool(); - + for (i = 0; i < SG_MEMPOOL_NR; i++) { + struct scsi_host_sg_pool *sgp = scsi_sg_pools + i; + mempool_destroy(sgp->pool); + kmem_cache_destroy(sgp->slab); + sgp->pool = NULL; + sgp->slab = NULL; + } } module_init(init_scsi); diff --git a/drivers/scsi/scsi.h b/drivers/scsi/scsi.h index 74ce5398b..b8ad3f4aa 100644 --- a/drivers/scsi/scsi.h +++ b/drivers/scsi/scsi.h @@ -439,6 +439,12 @@ extern int scsi_partsize(struct buffer_head *bh, unsigned long capacity, unsigned int *secs); /* + * sg list allocations + */ +struct scatterlist *scsi_alloc_sgtable(Scsi_Cmnd *SCpnt, int gfp_mask); +void scsi_free_sgtable(struct scatterlist *sgl, int index); + +/* * Prototypes for functions in scsi_dma.c */ void scsi_resize_dma_pool(void); diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 4bc544ed3..fda3c6528 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -182,7 +182,6 @@ static void scsi_dump(Scsi_Cmnd * SCpnt, int flag) }; printk("\n"); #endif - printk("DMA free %d sectors.\n", scsi_dma_free_sectors); } int scsi_debug_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *)) diff --git a/drivers/scsi/scsi_dma.c b/drivers/scsi/scsi_dma.c deleted file mode 100644 index 0d5ad403b..000000000 --- a/drivers/scsi/scsi_dma.c +++ /dev/null @@ -1,448 +0,0 @@ -/* - * scsi_dma.c Copyright (C) 2000 Eric Youngdale - * - * mid-level SCSI DMA bounce buffer allocator - * - */ - -#define __NO_VERSION__ -#include <linux/config.h> -#include <linux/module.h> -#include <linux/blk.h> - - -#include "scsi.h" -#include "hosts.h" -#include "constants.h" - -#ifdef CONFIG_KMOD -#include <linux/kmod.h> -#endif - -/* - * PAGE_SIZE must be a multiple of the sector size (512). True - * for all reasonably recent architectures (even the VAX...). - */ -#define SECTOR_SIZE 512 -#define SECTORS_PER_PAGE (PAGE_SIZE/SECTOR_SIZE) - -#if SECTORS_PER_PAGE <= 8 -typedef unsigned char FreeSectorBitmap; -#elif SECTORS_PER_PAGE <= 32 -typedef unsigned int FreeSectorBitmap; -#else -#error You lose. -#endif - -/* - * Used for access to internal allocator used for DMA safe buffers. - */ -static spinlock_t allocator_request_lock = SPIN_LOCK_UNLOCKED; - -static FreeSectorBitmap *dma_malloc_freelist = NULL; -static int need_isa_bounce_buffers; -static unsigned int dma_sectors = 0; -unsigned int scsi_dma_free_sectors = 0; -unsigned int scsi_need_isa_buffer = 0; -static unsigned char **dma_malloc_pages = NULL; - -/* - * Function: scsi_malloc - * - * Purpose: Allocate memory from the DMA-safe pool. - * - * Arguments: len - amount of memory we need. - * - * Lock status: No locks assumed to be held. This function is SMP-safe. - * - * Returns: Pointer to memory block. - * - * Notes: Prior to the new queue code, this function was not SMP-safe. - * This function can only allocate in units of sectors - * (i.e. 512 bytes). - * - * We cannot use the normal system allocator becuase we need - * to be able to guarantee that we can process a complete disk - * I/O request without touching the system allocator. Think - * about it - if the system were heavily swapping, and tried to - * write out a block of memory to disk, and the SCSI code needed - * to allocate more memory in order to be able to write the - * data to disk, you would wedge the system. - */ -void *scsi_malloc(unsigned int len) -{ - unsigned int nbits, mask; - unsigned long flags; - - int i, j; - if (len % SECTOR_SIZE != 0 || len > PAGE_SIZE) - return NULL; - - nbits = len >> 9; - mask = (1 << nbits) - 1; - - spin_lock_irqsave(&allocator_request_lock, flags); - - for (i = 0; i < dma_sectors / SECTORS_PER_PAGE; i++) - for (j = 0; j <= SECTORS_PER_PAGE - nbits; j++) { - if ((dma_malloc_freelist[i] & (mask << j)) == 0) { - dma_malloc_freelist[i] |= (mask << j); - scsi_dma_free_sectors -= nbits; -#ifdef DEBUG - SCSI_LOG_MLQUEUE(3, printk("SMalloc: %d %p [From:%p]\n", len, dma_malloc_pages[i] + (j << 9))); - printk("SMalloc: %d %p [From:%p]\n", len, dma_malloc_pages[i] + (j << 9)); -#endif - spin_unlock_irqrestore(&allocator_request_lock, flags); - return (void *) ((unsigned long) dma_malloc_pages[i] + (j << 9)); - } - } - spin_unlock_irqrestore(&allocator_request_lock, flags); - return NULL; /* Nope. No more */ -} - -/* - * Function: scsi_free - * - * Purpose: Free memory into the DMA-safe pool. - * - * Arguments: ptr - data block we are freeing. - * len - size of block we are freeing. - * - * Lock status: No locks assumed to be held. This function is SMP-safe. - * - * Returns: Nothing - * - * Notes: This function *must* only be used to free memory - * allocated from scsi_malloc(). - * - * Prior to the new queue code, this function was not SMP-safe. - * This function can only allocate in units of sectors - * (i.e. 512 bytes). - */ -int scsi_free(void *obj, unsigned int len) -{ - unsigned int page, sector, nbits, mask; - unsigned long flags; - -#ifdef DEBUG - unsigned long ret = 0; - -#ifdef __mips__ - __asm__ __volatile__("move\t%0,$31":"=r"(ret)); -#else - ret = __builtin_return_address(0); -#endif - printk("scsi_free %p %d\n", obj, len); - SCSI_LOG_MLQUEUE(3, printk("SFree: %p %d\n", obj, len)); -#endif - - spin_lock_irqsave(&allocator_request_lock, flags); - - for (page = 0; page < dma_sectors / SECTORS_PER_PAGE; page++) { - unsigned long page_addr = (unsigned long) dma_malloc_pages[page]; - if ((unsigned long) obj >= page_addr && - (unsigned long) obj < page_addr + PAGE_SIZE) { - sector = (((unsigned long) obj) - page_addr) >> 9; - - nbits = len >> 9; - mask = (1 << nbits) - 1; - - if (sector + nbits > SECTORS_PER_PAGE) - panic("scsi_free:Bad memory alignment"); - - if ((dma_malloc_freelist[page] & - (mask << sector)) != (mask << sector)) { -#ifdef DEBUG - printk("scsi_free(obj=%p, len=%d) called from %08lx\n", - obj, len, ret); -#endif - panic("scsi_free:Trying to free unused memory"); - } - scsi_dma_free_sectors += nbits; - dma_malloc_freelist[page] &= ~(mask << sector); - spin_unlock_irqrestore(&allocator_request_lock, flags); - return 0; - } - } - panic("scsi_free:Bad offset"); -} - - -/* - * Function: scsi_resize_dma_pool - * - * Purpose: Ensure that the DMA pool is sufficiently large to be - * able to guarantee that we can always process I/O requests - * without calling the system allocator. - * - * Arguments: None. - * - * Lock status: No locks assumed to be held. This function is SMP-safe. - * - * Returns: Nothing - * - * Notes: Prior to the new queue code, this function was not SMP-safe. - * Go through the device list and recompute the most appropriate - * size for the dma pool. Then grab more memory (as required). - */ -void scsi_resize_dma_pool(void) -{ - int i, k; - unsigned long size; - unsigned long flags; - struct Scsi_Host *shpnt; - struct Scsi_Host *host = NULL; - Scsi_Device *SDpnt; - FreeSectorBitmap *new_dma_malloc_freelist = NULL; - unsigned int new_dma_sectors = 0; - unsigned int new_need_isa_buffer = 0; - unsigned char **new_dma_malloc_pages = NULL; - int out_of_space = 0; - - spin_lock_irqsave(&allocator_request_lock, flags); - - if (!scsi_hostlist) { - /* - * Free up the DMA pool. - */ - if (scsi_dma_free_sectors != dma_sectors) - panic("SCSI DMA pool memory leak %d %d\n", scsi_dma_free_sectors, dma_sectors); - - for (i = 0; i < dma_sectors / SECTORS_PER_PAGE; i++) - free_pages((unsigned long) dma_malloc_pages[i], 0); - if (dma_malloc_pages) - kfree((char *) dma_malloc_pages); - dma_malloc_pages = NULL; - if (dma_malloc_freelist) - kfree((char *) dma_malloc_freelist); - dma_malloc_freelist = NULL; - dma_sectors = 0; - scsi_dma_free_sectors = 0; - spin_unlock_irqrestore(&allocator_request_lock, flags); - return; - } - /* Next, check to see if we need to extend the DMA buffer pool */ - - new_dma_sectors = 2 * SECTORS_PER_PAGE; /* Base value we use */ - - if (__pa(high_memory) - 1 > ISA_DMA_THRESHOLD) - need_isa_bounce_buffers = 1; - else - need_isa_bounce_buffers = 0; - - if (scsi_devicelist) - for (shpnt = scsi_hostlist; shpnt; shpnt = shpnt->next) - new_dma_sectors += SECTORS_PER_PAGE; /* Increment for each host */ - - for (host = scsi_hostlist; host; host = host->next) { - for (SDpnt = host->host_queue; SDpnt; SDpnt = SDpnt->next) { - /* - * sd and sr drivers allocate scatterlists. - * sr drivers may allocate for each command 1x2048 or 2x1024 extra - * buffers for 2k sector size and 1k fs. - * sg driver allocates buffers < 4k. - * st driver does not need buffers from the dma pool. - * estimate 4k buffer/command for devices of unknown type (should panic). - */ - if (SDpnt->type == TYPE_WORM || SDpnt->type == TYPE_ROM || - SDpnt->type == TYPE_DISK || SDpnt->type == TYPE_MOD) { - /* XXX We should not be using scsi_malloc() for - * XXX scatterlists. MUST FIXME -DaveM - */ - int nents = PAGE_SIZE / sizeof(struct scatterlist); - - new_dma_sectors += ((nents * - sizeof(struct scatterlist) + 511) >> 9) * - SDpnt->queue_depth; - if (SDpnt->type == TYPE_WORM || SDpnt->type == TYPE_ROM) - new_dma_sectors += (2048 >> 9) * SDpnt->queue_depth; - } else if (SDpnt->type == TYPE_SCANNER || - SDpnt->type == TYPE_PROCESSOR || - SDpnt->type == TYPE_COMM || - SDpnt->type == TYPE_MEDIUM_CHANGER || - SDpnt->type == TYPE_ENCLOSURE) { - new_dma_sectors += (4096 >> 9) * SDpnt->queue_depth; - } else { - if (SDpnt->type != TYPE_TAPE) { - printk("resize_dma_pool: unknown device type %d\n", SDpnt->type); - new_dma_sectors += (4096 >> 9) * SDpnt->queue_depth; - } - } - - if (host->unchecked_isa_dma && - need_isa_bounce_buffers && - SDpnt->type != TYPE_TAPE) { - new_dma_sectors += (PAGE_SIZE >> 9) * host->sg_tablesize * - SDpnt->queue_depth; - new_need_isa_buffer++; - } - } - } - -#ifdef DEBUG_INIT - printk("resize_dma_pool: needed dma sectors = %d\n", new_dma_sectors); -#endif - - /* limit DMA memory to 32MB: */ - new_dma_sectors = (new_dma_sectors + 15) & 0xfff0; - - /* - * We never shrink the buffers - this leads to - * race conditions that I would rather not even think - * about right now. - */ -#if 0 /* Why do this? No gain and risks out_of_space */ - if (new_dma_sectors < dma_sectors) - new_dma_sectors = dma_sectors; -#endif - if (new_dma_sectors <= dma_sectors) { - spin_unlock_irqrestore(&allocator_request_lock, flags); - return; /* best to quit while we are in front */ - } - - for (k = 0; k < 20; ++k) { /* just in case */ - out_of_space = 0; - size = (new_dma_sectors / SECTORS_PER_PAGE) * - sizeof(FreeSectorBitmap); - new_dma_malloc_freelist = (FreeSectorBitmap *) - kmalloc(size, GFP_ATOMIC); - if (new_dma_malloc_freelist) { - memset(new_dma_malloc_freelist, 0, size); - size = (new_dma_sectors / SECTORS_PER_PAGE) * - sizeof(*new_dma_malloc_pages); - new_dma_malloc_pages = (unsigned char **) - kmalloc(size, GFP_ATOMIC); - if (!new_dma_malloc_pages) { - size = (new_dma_sectors / SECTORS_PER_PAGE) * - sizeof(FreeSectorBitmap); - kfree((char *) new_dma_malloc_freelist); - out_of_space = 1; - } else { - memset(new_dma_malloc_pages, 0, size); - } - } else - out_of_space = 1; - - if ((!out_of_space) && (new_dma_sectors > dma_sectors)) { - for (i = dma_sectors / SECTORS_PER_PAGE; - i < new_dma_sectors / SECTORS_PER_PAGE; i++) { - new_dma_malloc_pages[i] = (unsigned char *) - __get_free_pages(GFP_ATOMIC | GFP_DMA, 0); - if (!new_dma_malloc_pages[i]) - break; - } - if (i != new_dma_sectors / SECTORS_PER_PAGE) { /* clean up */ - int k = i; - - out_of_space = 1; - for (i = 0; i < k; ++i) - free_pages((unsigned long) new_dma_malloc_pages[i], 0); - } - } - if (out_of_space) { /* try scaling down new_dma_sectors request */ - printk("scsi::resize_dma_pool: WARNING, dma_sectors=%u, " - "wanted=%u, scaling\n", dma_sectors, new_dma_sectors); - if (new_dma_sectors < (8 * SECTORS_PER_PAGE)) - break; /* pretty well hopeless ... */ - new_dma_sectors = (new_dma_sectors * 3) / 4; - new_dma_sectors = (new_dma_sectors + 15) & 0xfff0; - if (new_dma_sectors <= dma_sectors) - break; /* stick with what we have got */ - } else - break; /* found space ... */ - } /* end of for loop */ - if (out_of_space) { - spin_unlock_irqrestore(&allocator_request_lock, flags); - scsi_need_isa_buffer = new_need_isa_buffer; /* some useful info */ - printk(" WARNING, not enough memory, pool not expanded\n"); - return; - } - /* When we dick with the actual DMA list, we need to - * protect things - */ - if (dma_malloc_freelist) { - size = (dma_sectors / SECTORS_PER_PAGE) * sizeof(FreeSectorBitmap); - memcpy(new_dma_malloc_freelist, dma_malloc_freelist, size); - kfree((char *) dma_malloc_freelist); - } - dma_malloc_freelist = new_dma_malloc_freelist; - - if (dma_malloc_pages) { - size = (dma_sectors / SECTORS_PER_PAGE) * sizeof(*dma_malloc_pages); - memcpy(new_dma_malloc_pages, dma_malloc_pages, size); - kfree((char *) dma_malloc_pages); - } - scsi_dma_free_sectors += new_dma_sectors - dma_sectors; - dma_malloc_pages = new_dma_malloc_pages; - dma_sectors = new_dma_sectors; - scsi_need_isa_buffer = new_need_isa_buffer; - - spin_unlock_irqrestore(&allocator_request_lock, flags); - -#ifdef DEBUG_INIT - printk("resize_dma_pool: dma free sectors = %d\n", scsi_dma_free_sectors); - printk("resize_dma_pool: dma sectors = %d\n", dma_sectors); - printk("resize_dma_pool: need isa buffers = %d\n", scsi_need_isa_buffer); -#endif -} - -/* - * Function: scsi_init_minimal_dma_pool - * - * Purpose: Allocate a minimal (1-page) DMA pool. - * - * Arguments: None. - * - * Lock status: No locks assumed to be held. This function is SMP-safe. - * - * Returns: Nothing - * - * Notes: - */ -int scsi_init_minimal_dma_pool(void) -{ - unsigned long size; - unsigned long flags; - int has_space = 0; - - spin_lock_irqsave(&allocator_request_lock, flags); - - dma_sectors = PAGE_SIZE / SECTOR_SIZE; - scsi_dma_free_sectors = dma_sectors; - /* - * Set up a minimal DMA buffer list - this will be used during scan_scsis - * in some cases. - */ - - /* One bit per sector to indicate free/busy */ - size = (dma_sectors / SECTORS_PER_PAGE) * sizeof(FreeSectorBitmap); - dma_malloc_freelist = (FreeSectorBitmap *) - kmalloc(size, GFP_ATOMIC); - if (dma_malloc_freelist) { - memset(dma_malloc_freelist, 0, size); - /* One pointer per page for the page list */ - dma_malloc_pages = (unsigned char **) kmalloc( - (dma_sectors / SECTORS_PER_PAGE) * sizeof(*dma_malloc_pages), - GFP_ATOMIC); - if (dma_malloc_pages) { - memset(dma_malloc_pages, 0, size); - dma_malloc_pages[0] = (unsigned char *) - __get_free_pages(GFP_ATOMIC | GFP_DMA, 0); - if (dma_malloc_pages[0]) - has_space = 1; - } - } - if (!has_space) { - if (dma_malloc_freelist) { - kfree((char *) dma_malloc_freelist); - if (dma_malloc_pages) - kfree((char *) dma_malloc_pages); - } - spin_unlock_irqrestore(&allocator_request_lock, flags); - printk("scsi::init_module: failed, out of memory\n"); - return 1; - } - - spin_unlock_irqrestore(&allocator_request_lock, flags); - return 0; -} diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c index dc4681cd4..f64d20090 100644 --- a/drivers/scsi/scsi_ioctl.c +++ b/drivers/scsi/scsi_ioctl.c @@ -78,8 +78,7 @@ static int ioctl_probe(struct Scsi_Host *host, void *buffer) * *(char *) ((int *) arg)[2] the actual command byte. * * Note that if more than MAX_BUF bytes are requested to be transferred, - * the ioctl will fail with error EINVAL. MAX_BUF can be increased in - * the future by increasing the size that scsi_malloc will accept. + * the ioctl will fail with error EINVAL. * * This size *does not* include the initial lengths that were passed. * @@ -197,10 +196,14 @@ int scsi_ioctl_send_command(Scsi_Device * dev, Scsi_Ioctl_Command * sic) unsigned int inlen, outlen, cmdlen; unsigned int needed, buf_needed; int timeout, retries, result; - int data_direction; + int data_direction, gfp_mask = GFP_KERNEL; if (!sic) return -EINVAL; + + if (dev->host->unchecked_isa_dma) + gfp_mask |= GFP_DMA; + /* * Verify that we can read at least this much. */ @@ -232,7 +235,7 @@ int scsi_ioctl_send_command(Scsi_Device * dev, Scsi_Ioctl_Command * sic) buf_needed = (buf_needed + 511) & ~511; if (buf_needed > MAX_BUF) buf_needed = MAX_BUF; - buf = (char *) scsi_malloc(buf_needed); + buf = (char *) kmalloc(buf_needed, gfp_mask); if (!buf) return -ENOMEM; memset(buf, 0, buf_needed); @@ -341,7 +344,7 @@ int scsi_ioctl_send_command(Scsi_Device * dev, Scsi_Ioctl_Command * sic) error: if (buf) - scsi_free(buf, buf_needed); + kfree(buf); return result; diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 9ddf48635..317f21858 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -461,13 +461,13 @@ static void scsi_release_buffers(Scsi_Cmnd * SCpnt) if (bbpnt) { for (i = 0; i < SCpnt->use_sg; i++) { if (bbpnt[i]) - scsi_free(sgpnt[i].address, sgpnt[i].length); + kfree(sgpnt[i].address); } } - scsi_free(SCpnt->request_buffer, SCpnt->sglist_len); + scsi_free_sgtable(SCpnt->request_buffer, SCpnt->sglist_len); } else { if (SCpnt->request_buffer != req->buffer) - scsi_free(SCpnt->request_buffer,SCpnt->request_bufflen); + kfree(SCpnt->request_buffer); } /* @@ -541,11 +541,11 @@ void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors, sgpnt[i].address, sgpnt[i].length); } - scsi_free(sgpnt[i].address, sgpnt[i].length); + kfree(sgpnt[i].address); } } } - scsi_free(SCpnt->buffer, SCpnt->sglist_len); + scsi_free_sgtable(SCpnt->buffer, SCpnt->sglist_len); } else { if (SCpnt->buffer != req->buffer) { if (rq_data_dir(req) == READ) { @@ -555,7 +555,7 @@ void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors, memcpy(to, SCpnt->buffer, SCpnt->bufflen); bio_kunmap_irq(to, &flags); } - scsi_free(SCpnt->buffer, SCpnt->bufflen); + kfree(SCpnt->buffer); } } diff --git a/drivers/scsi/scsi_merge.c b/drivers/scsi/scsi_merge.c index 323207132..72ac525db 100644 --- a/drivers/scsi/scsi_merge.c +++ b/drivers/scsi/scsi_merge.c @@ -59,10 +59,9 @@ */ int scsi_init_io(Scsi_Cmnd *SCpnt) { - int count; - struct request * req; - struct scatterlist * sgpnt; - int this_count; + struct request *req; + struct scatterlist *sgpnt; + int count, gfp_mask; req = &SCpnt->request; @@ -78,32 +77,13 @@ int scsi_init_io(Scsi_Cmnd *SCpnt) */ SCpnt->use_sg = count; - /* - * Allocate the actual scatter-gather table itself. - */ - SCpnt->sglist_len = (SCpnt->use_sg * sizeof(struct scatterlist)); + gfp_mask = GFP_NOIO; + if (in_interrupt()) + gfp_mask &= ~__GFP_WAIT; - /* scsi_malloc can only allocate in chunks of 512 bytes so - * round it up. - */ - SCpnt->sglist_len = (SCpnt->sglist_len + 511) & ~511; - - sgpnt = (struct scatterlist *) scsi_malloc(SCpnt->sglist_len); - - if (!sgpnt) { - struct Scsi_Host *SHpnt = SCpnt->host; - - /* - * If we cannot allocate the scatter-gather table, then - * simply write the first buffer all by itself. - */ - printk("Warning - running *really* short on DMA buffers\n"); - this_count = req->current_nr_sectors; - printk("SCSI: depth is %d, # phys segs %d, # hw segs %d\n", SHpnt->host_busy, req->nr_phys_segments, req->nr_hw_segments); - goto single_segment; - } + sgpnt = scsi_alloc_sgtable(SCpnt, gfp_mask); + BUG_ON(!sgpnt); - memset(sgpnt, 0, SCpnt->sglist_len); SCpnt->request_buffer = (char *) sgpnt; SCpnt->request_bufflen = 0; req->buffer = NULL; @@ -116,29 +96,18 @@ int scsi_init_io(Scsi_Cmnd *SCpnt) count = blk_rq_map_sg(req->q, req, SCpnt->request_buffer); /* - * Verify that the count is correct. + * mapped well, send it off */ - if (count > SCpnt->use_sg) { - printk("Incorrect number of segments after building list\n"); - printk("counted %d, received %d\n", count, SCpnt->use_sg); - printk("req nr_sec %lu, cur_nr_sec %u\n", req->nr_sectors, req->current_nr_sectors); - scsi_free(SCpnt->request_buffer, SCpnt->sglist_len); - this_count = req->current_nr_sectors; - goto single_segment; + if (count <= SCpnt->use_sg) { + SCpnt->use_sg = count; + return 1; } - SCpnt->use_sg = count; - return 1; - -single_segment: - /* - * Come here if for any reason we choose to do this as a single - * segment. FIXME: remember to handle highmem bouncing - */ - SCpnt->request_bufflen = this_count << 9; - SCpnt->request_buffer = bio_data(req->bio); - SCpnt->use_sg = 0; - return 1; + printk("Incorrect number of segments after building list\n"); + printk("counted %d, received %d\n", count, SCpnt->use_sg); + printk("req nr_sec %lu, cur_nr_sec %u\n", req->nr_sectors, req->current_nr_sectors); + BUG(); + return 0; /* ahem */ } /* @@ -175,7 +144,7 @@ void scsi_initialize_merge_fn(Scsi_Device * SDpnt) bounce_limit = SHpnt->pci_dev->dma_mask; } if (SHpnt->unchecked_isa_dma) - bounce_limit = ISA_DMA_THRESHOLD; + bounce_limit = BLK_BOUNCE_ISA; blk_queue_bounce_limit(q, bounce_limit); } diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index e6cac9755..9cd871b0c 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -390,8 +390,6 @@ void scan_scsis(struct Scsi_Host *shpnt, } } } - scsi_resize_dma_pool(); - for (sdtpnt = scsi_devicelist; sdtpnt; sdtpnt = sdtpnt->next) { if (sdtpnt->finish && sdtpnt->nr_dev) { (*sdtpnt->finish) (); diff --git a/drivers/scsi/scsi_syms.c b/drivers/scsi/scsi_syms.c index 7fb246998..dbe14bacb 100644 --- a/drivers/scsi/scsi_syms.c +++ b/drivers/scsi/scsi_syms.c @@ -33,8 +33,6 @@ */ EXPORT_SYMBOL(scsi_register_module); EXPORT_SYMBOL(scsi_unregister_module); -EXPORT_SYMBOL(scsi_free); -EXPORT_SYMBOL(scsi_malloc); EXPORT_SYMBOL(scsi_register); EXPORT_SYMBOL(scsi_unregister); EXPORT_SYMBOL(scsicam_bios_param); @@ -48,9 +46,7 @@ EXPORT_SYMBOL(print_sense); EXPORT_SYMBOL(print_req_sense); EXPORT_SYMBOL(print_msg); EXPORT_SYMBOL(print_status); -EXPORT_SYMBOL(scsi_dma_free_sectors); EXPORT_SYMBOL(kernel_scsi_ioctl); -EXPORT_SYMBOL(scsi_need_isa_buffer); EXPORT_SYMBOL(scsi_release_command); EXPORT_SYMBOL(print_Scsi_Cmnd); EXPORT_SYMBOL(scsi_block_when_processing_errors); diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 8c7c31f31..7bada9dd8 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -765,7 +765,7 @@ static int sd_init_onedisk(int i) return i; } - buffer = (unsigned char *) scsi_malloc(512); + buffer = kmalloc(512, GFP_DMA); if (!buffer) { printk(KERN_WARNING "(sd_init_onedisk:) Memory allocation failure.\n"); scsi_release_request(SRpnt); @@ -1042,7 +1042,7 @@ static int sd_init_onedisk(int i) scsi_release_request(SRpnt); SRpnt = NULL; - scsi_free(buffer, 512); + kfree(buffer); return i; } diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 8d5a291e4..2c2a9fa43 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -2459,9 +2459,8 @@ static char * sg_low_malloc(int rqSz, int lowDma, int mem_src, int * retSzp) rqSz = num_sect * SG_SECTOR_SZ; } while (num_sect > 0) { - if ((num_sect <= sg_pool_secs_avail) && - (scsi_dma_free_sectors > (SG_LOW_POOL_THRESHHOLD + num_sect))) { - resp = scsi_malloc(rqSz); + if ((num_sect <= sg_pool_secs_avail)) { + resp = kmalloc(rqSz, page_mask); if (resp) { if (retSzp) *retSzp = rqSz; sg_pool_secs_avail -= num_sect; @@ -2563,7 +2562,7 @@ static void sg_low_free(char * buff, int size, int mem_src) { int num_sect = size / SG_SECTOR_SZ; - scsi_free(buff, size); + kfree(buff); sg_pool_secs_avail += num_sect; } break; @@ -2869,9 +2868,8 @@ static int sg_proc_debug_info(char * buffer, int * len, off_t * begin, max_dev = sg_last_dev(); PRINT_PROC("dev_max(currently)=%d max_active_device=%d (origin 1)\n", sg_template.dev_max, max_dev); - PRINT_PROC(" scsi_dma_free_sectors=%u sg_pool_secs_aval=%d " - "def_reserved_size=%d\n", - scsi_dma_free_sectors, sg_pool_secs_avail, sg_big_buff); + PRINT_PROC(" sg_pool_secs_aval=%d def_reserved_size=%d\n", + sg_pool_secs_avail, sg_big_buff); for (j = 0; j < max_dev; ++j) { if ((sdp = sg_get_dev(j))) { Sg_fd * fp; diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 89b10acb4..530f89385 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -258,112 +258,6 @@ static request_queue_t *sr_find_queue(kdev_t dev) return &scsi_CDs[MINOR(dev)].device->request_queue; } -static int sr_scatter_pad(Scsi_Cmnd *SCpnt, int s_size) -{ - struct scatterlist *sg, *old_sg = NULL; - int i, fsize, bsize, sg_ent, sg_count; - char *front, *back; - void **bbpnt, **old_bbpnt = NULL; - - back = front = NULL; - sg_ent = SCpnt->use_sg; - bsize = 0; /* gcc... */ - - /* - * need front pad - */ - if ((fsize = SCpnt->request.sector % (s_size >> 9))) { - fsize <<= 9; - sg_ent++; - if ((front = scsi_malloc(fsize)) == NULL) - goto no_mem; - } - /* - * need a back pad too - */ - if ((bsize = s_size - ((SCpnt->request_bufflen + fsize) % s_size))) { - sg_ent++; - if ((back = scsi_malloc(bsize)) == NULL) - goto no_mem; - } - - /* - * extend or allocate new scatter-gather table - */ - sg_count = SCpnt->use_sg; - if (sg_count) { - old_sg = (struct scatterlist *) SCpnt->request_buffer; - old_bbpnt = SCpnt->bounce_buffers; - } else { - sg_count = 1; - sg_ent++; - } - - /* Get space for scatterlist and bounce buffer array. */ - i = sg_ent * sizeof(struct scatterlist); - i += sg_ent * sizeof(void *); - i = (i + 511) & ~511; - - if ((sg = scsi_malloc(i)) == NULL) - goto no_mem; - - bbpnt = (void **) - ((char *)sg + (sg_ent * sizeof(struct scatterlist))); - - /* - * no more failing memory allocs possible, we can safely assign - * SCpnt values now - */ - SCpnt->sglist_len = i; - SCpnt->use_sg = sg_count; - memset(sg, 0, SCpnt->sglist_len); - - i = 0; - if (fsize) { - sg[0].address = bbpnt[0] = front; - sg[0].length = fsize; - i++; - } - if (old_sg) { - memcpy(sg + i, old_sg, SCpnt->use_sg * sizeof(struct scatterlist)); - if (old_bbpnt) - memcpy(bbpnt + i, old_bbpnt, SCpnt->use_sg * sizeof(void *)); - scsi_free(old_sg, (((SCpnt->use_sg * sizeof(struct scatterlist)) + - (SCpnt->use_sg * sizeof(void *))) + 511) & ~511); - } else { - sg[i].address = NULL; - sg[i].page = virt_to_page(SCpnt->request_buffer); - sg[i].offset = (unsigned long) SCpnt->request_buffer&~PAGE_MASK; - sg[i].length = SCpnt->request_bufflen; - } - - SCpnt->request_bufflen += (fsize + bsize); - SCpnt->request_buffer = sg; - SCpnt->bounce_buffers = bbpnt; - SCpnt->use_sg += i; - - if (bsize) { - sg[SCpnt->use_sg].address = NULL; - sg[SCpnt->use_sg].page = virt_to_page(back); - sg[SCpnt->use_sg].offset = (unsigned long) back & ~PAGE_MASK; - bbpnt[SCpnt->use_sg] = back; - sg[SCpnt->use_sg].length = bsize; - SCpnt->use_sg++; - } - - return 0; - -no_mem: - printk("sr: ran out of mem for scatter pad\n"); - if (front) - scsi_free(front, fsize); - if (back) - scsi_free(back, bsize); - - return 1; -} - - static int sr_init_command(Scsi_Cmnd * SCpnt) { int dev, devm, block=0, this_count, s_size; @@ -428,14 +322,11 @@ static int sr_init_command(Scsi_Cmnd * SCpnt) /* * request doesn't start on hw block boundary, add scatter pads - * - * XXX Jens can this ever happen? The SCSI disk support code - * XXX marks this as a hard error. It would be nice to kill - * XXX off crap like sr_scatter_pad() -DaveM */ - if ((SCpnt->request.sector % (s_size >> 9)) || (SCpnt->request_bufflen % s_size)) - if (sr_scatter_pad(SCpnt, s_size)) - return 0; + if ((SCpnt->request.sector % (s_size >> 9)) || (SCpnt->request_bufflen % s_size)) { + printk("sr: unaligned transfer\n"); + return 0; + } this_count = (SCpnt->request_bufflen >> 9) / (s_size >> 9); @@ -587,7 +478,7 @@ void get_sectorsize(int i) int sector_size; Scsi_Request *SRpnt; - buffer = (unsigned char *) scsi_malloc(512); + buffer = (unsigned char *) kmalloc(512, GFP_DMA); SRpnt = scsi_allocate_request(scsi_CDs[i].device); if(buffer == NULL || SRpnt == NULL) @@ -596,7 +487,7 @@ void get_sectorsize(int i) sector_size = 2048; /* A guess, just in case */ scsi_CDs[i].needs_sector_size = 1; if(buffer) - scsi_free(buffer, 512); + kfree(buffer); if(SRpnt) scsi_release_request(SRpnt); return; @@ -677,7 +568,7 @@ void get_sectorsize(int i) sr_sizes[i] = scsi_CDs[i].capacity >> (BLOCK_SIZE_BITS - 9); }; blk_queue_hardsect_size(blk_get_queue(MAJOR_NR), sector_size); - scsi_free(buffer, 512); + kfree(buffer); } void get_capabilities(int i) @@ -698,7 +589,7 @@ void get_capabilities(int i) "" }; - buffer = (unsigned char *) scsi_malloc(512); + buffer = (unsigned char *) kmalloc(512, GFP_DMA); if (!buffer) { printk(KERN_ERR "sr: out of memory.\n"); @@ -718,7 +609,7 @@ void get_capabilities(int i) scsi_CDs[i].cdi.mask |= (CDC_CD_R | CDC_CD_RW | CDC_DVD_R | CDC_DVD | CDC_DVD_RAM | CDC_SELECT_DISC | CDC_SELECT_SPEED); - scsi_free(buffer, 512); + kfree(buffer); printk("sr%i: scsi-1 drive\n", i); return; } @@ -771,7 +662,7 @@ void get_capabilities(int i) /*else I don't think it can close its tray scsi_CDs[i].cdi.mask |= CDC_CLOSE_TRAY; */ - scsi_free(buffer, 512); + kfree(buffer); } /* diff --git a/drivers/scsi/sr_ioctl.c b/drivers/scsi/sr_ioctl.c index 3c3a53ad4..da3ec60fe 100644 --- a/drivers/scsi/sr_ioctl.c +++ b/drivers/scsi/sr_ioctl.c @@ -95,7 +95,7 @@ int sr_do_ioctl(int target, unsigned char *sr_cmd, void *buffer, unsigned buflen SRpnt->sr_request.buffer = buffer; if (buffer && SRpnt->sr_host->unchecked_isa_dma && (virt_to_phys(buffer) + buflength - 1 > ISA_DMA_THRESHOLD)) { - bounce_buffer = (char *) scsi_malloc((buflength + 511) & ~511); + bounce_buffer = (char *) kmalloc(buflength, GFP_DMA); if (bounce_buffer == NULL) { printk("SCSI DMA pool exhausted."); return -ENOMEM; @@ -114,7 +114,7 @@ int sr_do_ioctl(int target, unsigned char *sr_cmd, void *buffer, unsigned buflen req = &SRpnt->sr_request; if (SRpnt->sr_buffer && req->buffer && SRpnt->sr_buffer != req->buffer) { memcpy(req->buffer, SRpnt->sr_buffer, SRpnt->sr_bufflen); - scsi_free(SRpnt->sr_buffer, (SRpnt->sr_bufflen + 511) & ~511); + kfree(SRpnt->sr_buffer); SRpnt->sr_buffer = req->buffer; } @@ -519,7 +519,7 @@ int sr_is_xa(int minor) if (!xa_test) return 0; - raw_sector = (unsigned char *) scsi_malloc(2048 + 512); + raw_sector = (unsigned char *) kmalloc(2048, GFP_DMA | GFP_KERNEL); if (!raw_sector) return -ENOMEM; if (0 == sr_read_sector(minor, scsi_CDs[minor].ms_offset + 16, @@ -529,7 +529,7 @@ int sr_is_xa(int minor) /* read a raw sector failed for some reason. */ is_xa = -1; } - scsi_free(raw_sector, 2048 + 512); + kfree(raw_sector); #ifdef DEBUG printk("sr%d: sr_is_xa: %d\n", minor, is_xa); #endif diff --git a/drivers/scsi/sr_vendor.c b/drivers/scsi/sr_vendor.c index 39bd3b6cb..a1d4a7db4 100644 --- a/drivers/scsi/sr_vendor.c +++ b/drivers/scsi/sr_vendor.c @@ -115,7 +115,7 @@ int sr_set_blocklength(int minor, int blocklength) density = (blocklength > 2048) ? 0x81 : 0x83; #endif - buffer = (unsigned char *) scsi_malloc(512); + buffer = (unsigned char *) kmalloc(512, GFP_KERNEL | GFP_DMA); if (!buffer) return -ENOMEM; @@ -142,7 +142,7 @@ int sr_set_blocklength(int minor, int blocklength) printk("sr%d: switching blocklength to %d bytes failed\n", minor, blocklength); #endif - scsi_free(buffer, 512); + kfree(buffer); return rc; } @@ -162,7 +162,7 @@ int sr_cd_check(struct cdrom_device_info *cdi) if (scsi_CDs[minor].cdi.mask & CDC_MULTI_SESSION) return 0; - buffer = (unsigned char *) scsi_malloc(512); + buffer = (unsigned char *) kmalloc(512, GFP_KERNEL | GFP_DMA); if (!buffer) return -ENOMEM; @@ -306,6 +306,6 @@ int sr_cd_check(struct cdrom_device_info *cdi) printk(KERN_DEBUG "sr%d: multisession offset=%lu\n", minor, sector); #endif - scsi_free(buffer, 512); + kfree(buffer); return rc; } diff --git a/drivers/scsi/sym53c8xx.c b/drivers/scsi/sym53c8xx.c index 826e32ab3..bc030dcb4 100644 --- a/drivers/scsi/sym53c8xx.c +++ b/drivers/scsi/sym53c8xx.c @@ -12174,7 +12174,7 @@ static int ncr_scatter(ncb_p np, ccb_p cp, Scsi_Cmnd *cmd) use_sg = map_scsi_sg_data(np, cmd); if (use_sg > MAX_SCATTER) { - unmap_scsi_sg_data(np, cmd); + unmap_scsi_data(np, cmd); return -1; } data = &cp->phys.data[MAX_SCATTER - use_sg]; diff --git a/drivers/scsi/sym53c8xx.h b/drivers/scsi/sym53c8xx.h index 6b4d584d5..256d34b64 100644 --- a/drivers/scsi/sym53c8xx.h +++ b/drivers/scsi/sym53c8xx.h @@ -96,7 +96,7 @@ int sym53c8xx_release(struct Scsi_Host *); this_id: 7, \ sg_tablesize: SCSI_NCR_SG_TABLESIZE, \ cmd_per_lun: SCSI_NCR_CMD_PER_LUN, \ - max_sectors: MAX_SEGMENTS*8, \ + max_sectors: MAX_HW_SEGMENTS*8, \ use_clustering: DISABLE_CLUSTERING, \ highmem_io: 1} diff --git a/fs/adfs/adfs.h b/fs/adfs/adfs.h index 30c400e5b..720b707a3 100644 --- a/fs/adfs/adfs.h +++ b/fs/adfs/adfs.h @@ -66,7 +66,7 @@ struct adfs_discmap { /* Inode stuff */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) -int adfs_get_block(struct inode *inode, long block, +int adfs_get_block(struct inode *inode, sector_t block, struct buffer_head *bh, int create); #else int adfs_bmap(struct inode *inode, int block); diff --git a/fs/adfs/dir_f.c b/fs/adfs/dir_f.c index ef7715c44..66a0c36a7 100644 --- a/fs/adfs/dir_f.c +++ b/fs/adfs/dir_f.c @@ -193,7 +193,7 @@ adfs_dir_read(struct super_block *sb, unsigned long object_id, goto release_buffers; } - dir->bh[blk] = bread(sb->s_dev, phys, sb->s_blocksize); + dir->bh[blk] = sb_bread(sb, phys); if (!dir->bh[blk]) goto release_buffers; } diff --git a/fs/adfs/dir_fplus.c b/fs/adfs/dir_fplus.c index 329bbd5f9..71064bc55 100644 --- a/fs/adfs/dir_fplus.c +++ b/fs/adfs/dir_fplus.c @@ -35,7 +35,7 @@ adfs_fplus_read(struct super_block *sb, unsigned int id, unsigned int sz, struct goto out; } - dir->bh[0] = bread(sb->s_dev, block, sb->s_blocksize); + dir->bh[0] = sb_bread(sb, block); if (!dir->bh[0]) goto out; dir->nr_buffers += 1; @@ -60,7 +60,7 @@ adfs_fplus_read(struct super_block *sb, unsigned int id, unsigned int sz, struct goto out; } - dir->bh[blk] = bread(sb->s_dev, block, sb->s_blocksize); + dir->bh[blk] = sb_bread(sb, block); if (!dir->bh[blk]) goto out; dir->nr_buffers = blk; diff --git a/fs/adfs/inode.c b/fs/adfs/inode.c index 22d9bfd25..9e402bcd9 100644 --- a/fs/adfs/inode.c +++ b/fs/adfs/inode.c @@ -27,7 +27,7 @@ * not support creation of new blocks, so we return -EIO for this case. */ int -adfs_get_block(struct inode *inode, long block, struct buffer_head *bh, int create) +adfs_get_block(struct inode *inode, sector_t block, struct buffer_head *bh, int create) { if (block < 0) goto abort_negative; diff --git a/fs/adfs/super.c b/fs/adfs/super.c index 00be08b38..f1af56308 100644 --- a/fs/adfs/super.c +++ b/fs/adfs/super.c @@ -263,7 +263,7 @@ static struct adfs_discmap *adfs_read_map(struct super_block *sb, struct adfs_di dm[zone].dm_startbit = 0; dm[zone].dm_endbit = zone_size; dm[zone].dm_startblk = zone * zone_size - ADFS_DR_SIZE_BITS; - dm[zone].dm_bh = bread(sb->s_dev, map_addr, sb->s_blocksize); + dm[zone].dm_bh = sb_bread(sb, map_addr); if (!dm[zone].dm_bh) { adfs_error(sb, "unable to read map"); @@ -319,8 +319,9 @@ struct super_block *adfs_read_super(struct super_block *sb, void *data, int sile if (parse_options(sb, data)) goto error; + sb->s_blocksize = BLOCK_SIZE; set_blocksize(dev, BLOCK_SIZE); - if (!(bh = bread(dev, ADFS_DISCRECORD / BLOCK_SIZE, BLOCK_SIZE))) { + if (!(bh = sb_bread(sb, ADFS_DISCRECORD / BLOCK_SIZE))) { adfs_error(sb, "unable to read superblock"); goto error; } @@ -354,7 +355,7 @@ struct super_block *adfs_read_super(struct super_block *sb, void *data, int sile brelse(bh); set_blocksize(dev, sb->s_blocksize); - bh = bread(dev, ADFS_DISCRECORD / sb->s_blocksize, sb->s_blocksize); + bh = sb_bread(sb, ADFS_DISCRECORD / sb->s_blocksize); if (!bh) { adfs_error(sb, "couldn't read superblock on " "2nd try."); diff --git a/fs/affs/super.c b/fs/affs/super.c index a2a034fc2..d65e44bb3 100644 --- a/fs/affs/super.c +++ b/fs/affs/super.c @@ -332,7 +332,7 @@ got_root: blocksize == 2048 ? 11 : 12; /* Find out which kind of FS we have */ - boot_bh = bread(sb->s_dev, 0, sb->s_blocksize); + boot_bh = sb_bread(sb, 0); if (!boot_bh) { printk(KERN_ERR "AFFS: Cannot read boot block\n"); goto out_error; diff --git a/fs/bfs/dir.c b/fs/bfs/dir.c index 5caf04a7b..5a8874890 100644 --- a/fs/bfs/dir.c +++ b/fs/bfs/dir.c @@ -41,7 +41,7 @@ static int bfs_readdir(struct file * f, void * dirent, filldir_t filldir) while (f->f_pos < dir->i_size) { offset = f->f_pos & (BFS_BSIZE-1); block = dir->iu_sblock + (f->f_pos >> BFS_BSIZE_BITS); - bh = bread(dev, block, BFS_BSIZE); + bh = sb_bread(dir->i_sb, block); if (!bh) { f->f_pos += BFS_BSIZE - offset; continue; @@ -270,7 +270,7 @@ static int bfs_add_entry(struct inode * dir, const char * name, int namelen, int sblock = dir->iu_sblock; eblock = dir->iu_eblock; for (block=sblock; block<=eblock; block++) { - bh = bread(dev, block, BFS_BSIZE); + bh = sb_bread(dir->i_sb, block); if(!bh) return -ENOSPC; for (off=0; off<BFS_BSIZE; off+=BFS_DIRENT_SIZE) { @@ -319,7 +319,7 @@ static struct buffer_head * bfs_find_entry(struct inode * dir, block = offset = 0; while (block * BFS_BSIZE + offset < dir->i_size) { if (!bh) { - bh = bread(dir->i_dev, dir->iu_sblock + block, BFS_BSIZE); + bh = sb_bread(dir->i_sb, dir->iu_sblock + block); if (!bh) { block++; continue; diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c index 6a4a4c548..f83f13f56 100644 --- a/fs/bfs/inode.c +++ b/fs/bfs/inode.c @@ -47,7 +47,7 @@ static void bfs_read_inode(struct inode * inode) } block = (ino - BFS_ROOT_INO)/BFS_INODES_PER_BLOCK + 1; - bh = bread(dev, block, BFS_BSIZE); + bh = sb_bread(inode->i_sb, block); if (!bh) { printf("Unable to read inode %s:%08lx\n", bdevname(dev), ino); make_bad_inode(inode); @@ -100,7 +100,7 @@ static void bfs_write_inode(struct inode * inode, int unused) lock_kernel(); block = (ino - BFS_ROOT_INO)/BFS_INODES_PER_BLOCK + 1; - bh = bread(dev, block, BFS_BSIZE); + bh = sb_bread(inode->i_sb, block); if (!bh) { printf("Unable to read inode %s:%08lx\n", bdevname(dev), ino); unlock_kernel(); @@ -153,7 +153,7 @@ static void bfs_delete_inode(struct inode * inode) lock_kernel(); mark_inode_dirty(inode); block = (ino - BFS_ROOT_INO)/BFS_INODES_PER_BLOCK + 1; - bh = bread(dev, block, BFS_BSIZE); + bh = sb_bread(s, block); if (!bh) { printf("Unable to read inode %s:%08lx\n", bdevname(dev), ino); unlock_kernel(); @@ -252,7 +252,7 @@ static struct super_block * bfs_read_super(struct super_block * s, s->s_blocksize = BFS_BSIZE; s->s_blocksize_bits = BFS_BSIZE_BITS; - bh = bread(dev, 0, BFS_BSIZE); + bh = sb_bread(s, 0); if(!bh) goto out; bfs_sb = (struct bfs_super_block *)bh->b_data; diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c index 7582c9dd8..7f4afb369 100644 --- a/fs/cramfs/inode.c +++ b/fs/cramfs/inode.c @@ -153,7 +153,7 @@ static void *cramfs_read(struct super_block *sb, unsigned int offset, unsigned i bh = NULL; if (blocknr + i < devsize) { - bh = getblk(sb->s_dev, blocknr + i, PAGE_CACHE_SIZE); + bh = sb_getblk(sb, blocknr + i); if (!buffer_uptodate(bh)) read_array[unread++] = bh; } diff --git a/fs/efs/dir.c b/fs/efs/dir.c index 9bba7a2cb..cc7df77a0 100644 --- a/fs/efs/dir.c +++ b/fs/efs/dir.c @@ -40,7 +40,7 @@ static int efs_readdir(struct file *filp, void *dirent, filldir_t filldir) { /* look at all blocks */ while (block < inode->i_blocks) { /* read the dir block */ - bh = bread(inode->i_dev, efs_bmap(inode, block), EFS_DIRBSIZE); + bh = sb_bread(inode->i_sb, efs_bmap(inode, block)); if (!bh) { printk(KERN_ERR "EFS: readdir(): failed to read dir block %d\n", block); diff --git a/fs/efs/inode.c b/fs/efs/inode.c index e27e376a5..67d050f22 100644 --- a/fs/efs/inode.c +++ b/fs/efs/inode.c @@ -77,7 +77,7 @@ void efs_read_inode(struct inode *inode) { (EFS_BLOCKSIZE / sizeof(struct efs_dinode))) * sizeof(struct efs_dinode); - bh = bread(inode->i_dev, block, EFS_BLOCKSIZE); + bh = sb_bread(inode->i_sb, block); if (!bh) { printk(KERN_WARNING "EFS: bread() failed at block %d\n", block); goto read_inode_error; @@ -271,7 +271,7 @@ efs_block_t efs_map_block(struct inode *inode, efs_block_t block) { if (first || lastblock != iblock) { if (bh) brelse(bh); - bh = bread(inode->i_dev, iblock, EFS_BLOCKSIZE); + bh = sb_bread(inode->i_sb, iblock); if (!bh) { printk(KERN_ERR "EFS: bread() failed at block %d\n", iblock); return 0; diff --git a/fs/efs/namei.c b/fs/efs/namei.c index cc85f5d9a..cc06bc8cb 100644 --- a/fs/efs/namei.c +++ b/fs/efs/namei.c @@ -24,7 +24,7 @@ static efs_ino_t efs_find_entry(struct inode *inode, const char *name, int len) for(block = 0; block < inode->i_blocks; block++) { - bh = bread(inode->i_dev, efs_bmap(inode, block), EFS_DIRBSIZE); + bh = sb_bread(inode->i_sb, efs_bmap(inode, block)); if (!bh) { printk(KERN_ERR "EFS: find_entry(): failed to read dir block %d\n", block); return 0; diff --git a/fs/efs/super.c b/fs/efs/super.c index 79ee8d837..691f6df84 100644 --- a/fs/efs/super.c +++ b/fs/efs/super.c @@ -137,11 +137,14 @@ struct super_block *efs_read_super(struct super_block *s, void *d, int silent) { struct buffer_head *bh; sb = SUPER_INFO(s); - + + s->s_magic = EFS_SUPER_MAGIC; + s->s_blocksize = EFS_BLOCKSIZE; + s->s_blocksize_bits = EFS_BLOCKSIZE_BITS; set_blocksize(dev, EFS_BLOCKSIZE); /* read the vh (volume header) block */ - bh = bread(dev, 0, EFS_BLOCKSIZE); + bh = sb_bread(s, 0); if (!bh) { printk(KERN_ERR "EFS: cannot read volume header\n"); @@ -160,7 +163,7 @@ struct super_block *efs_read_super(struct super_block *s, void *d, int silent) { goto out_no_fs_ul; } - bh = bread(dev, sb->fs_start + EFS_SUPER, EFS_BLOCKSIZE); + bh = sb_bread(s, sb->fs_start + EFS_SUPER); if (!bh) { printk(KERN_ERR "EFS: cannot read superblock\n"); goto out_no_fs_ul; @@ -174,10 +177,6 @@ struct super_block *efs_read_super(struct super_block *s, void *d, int silent) { goto out_no_fs_ul; } brelse(bh); - - s->s_magic = EFS_SUPER_MAGIC; - s->s_blocksize = EFS_BLOCKSIZE; - s->s_blocksize_bits = EFS_BLOCKSIZE_BITS; if (!(s->s_flags & MS_RDONLY)) { #ifdef DEBUG diff --git a/fs/efs/symlink.c b/fs/efs/symlink.c index b5d17f3cc..5dd10f50e 100644 --- a/fs/efs/symlink.c +++ b/fs/efs/symlink.c @@ -26,13 +26,13 @@ static int efs_symlink_readpage(struct file *file, struct page *page) lock_kernel(); /* read first 512 bytes of link target */ err = -EIO; - bh = bread(inode->i_dev, efs_bmap(inode, 0), EFS_BLOCKSIZE); + bh = sb_bread(inode->i_sb, efs_bmap(inode, 0)); if (!bh) goto fail; memcpy(link, bh->b_data, (size > EFS_BLOCKSIZE) ? EFS_BLOCKSIZE : size); brelse(bh); if (size > EFS_BLOCKSIZE) { - bh = bread(inode->i_dev, efs_bmap(inode, 1), EFS_BLOCKSIZE); + bh = sb_bread(inode->i_sb, efs_bmap(inode, 1)); if (!bh) goto fail; memcpy(link + EFS_BLOCKSIZE, bh->b_data, size - EFS_BLOCKSIZE); diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c index 3d799f7a0..da07d9462 100644 --- a/fs/ext2/balloc.c +++ b/fs/ext2/balloc.c @@ -88,7 +88,7 @@ static int read_block_bitmap (struct super_block * sb, if (!gdp) goto error_out; retval = 0; - bh = bread (sb->s_dev, le32_to_cpu(gdp->bg_block_bitmap), sb->s_blocksize); + bh = sb_bread(sb, le32_to_cpu(gdp->bg_block_bitmap)); if (!bh) { ext2_error (sb, "read_block_bitmap", "Cannot read block bitmap - " diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c index bcc088a37..46e7f2220 100644 --- a/fs/ext2/ialloc.c +++ b/fs/ext2/ialloc.c @@ -51,8 +51,7 @@ static struct buffer_head *read_inode_bitmap (struct super_block * sb, if (!desc) goto error_out; - bh = bread(sb->s_dev, le32_to_cpu(desc->bg_inode_bitmap), - sb->s_blocksize); + bh = sb_bread(sb, le32_to_cpu(desc->bg_inode_bitmap)); if (!bh) ext2_error (sb, "read_inode_bitmap", "Cannot read inode bitmap - " diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index 3665f5ef6..e96e1a014 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c @@ -239,8 +239,7 @@ static Indirect *ext2_get_branch(struct inode *inode, Indirect chain[4], int *err) { - kdev_t dev = inode->i_dev; - int size = inode->i_sb->s_blocksize; + struct super_block *sb = inode->i_sb; Indirect *p = chain; struct buffer_head *bh; @@ -250,7 +249,7 @@ static Indirect *ext2_get_branch(struct inode *inode, if (!p->key) goto no_block; while (--depth) { - bh = bread(dev, le32_to_cpu(p->key), size); + bh = sb_bread(sb, le32_to_cpu(p->key)); if (!bh) goto failure; /* Reader: pointers */ @@ -399,7 +398,7 @@ static int ext2_alloc_branch(struct inode *inode, * Get buffer_head for parent block, zero it out and set * the pointer to new one, then send parent to disk. */ - bh = getblk(inode->i_dev, parent, blocksize); + bh = sb_getblk(inode->i_sb, parent); lock_buffer(bh); memset(bh->b_data, 0, blocksize); branch[n].bh = bh; @@ -763,7 +762,7 @@ static void ext2_free_branches(struct inode *inode, u32 *p, u32 *q, int depth) if (!nr) continue; *p = 0; - bh = bread (inode->i_dev, nr, inode->i_sb->s_blocksize); + bh = sb_bread(inode->i_sb, nr); /* * A read failure? Report error and clear slot * (should be rare). @@ -921,7 +920,7 @@ void ext2_read_inode (struct inode * inode) EXT2_INODE_SIZE(inode->i_sb); block = le32_to_cpu(gdp[desc].bg_inode_table) + (offset >> EXT2_BLOCK_SIZE_BITS(inode->i_sb)); - if (!(bh = bread (inode->i_dev, block, inode->i_sb->s_blocksize))) { + if (!(bh = sb_bread(inode->i_sb, block))) { ext2_error (inode->i_sb, "ext2_read_inode", "unable to read inode block - " "inode=%lu, block=%lu", inode->i_ino, block); @@ -1063,7 +1062,7 @@ static int ext2_update_inode(struct inode * inode, int do_sync) EXT2_INODE_SIZE(inode->i_sb); block = le32_to_cpu(gdp[desc].bg_inode_table) + (offset >> EXT2_BLOCK_SIZE_BITS(inode->i_sb)); - if (!(bh = bread (inode->i_dev, block, inode->i_sb->s_blocksize))) { + if (!(bh = sb_bread(inode->i_sb, block))) { ext2_error (inode->i_sb, "ext2_write_inode", "unable to read inode block - " "inode=%lu, block=%lu", inode->i_ino, block); diff --git a/fs/ext2/super.c b/fs/ext2/super.c index e13a419bc..c9c544458 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c @@ -28,8 +28,6 @@ #include <asm/uaccess.h> -static void ext2_sync_super(struct super_block *sb, - struct ext2_super_block *es); static char error_buf[1024]; @@ -37,13 +35,13 @@ void ext2_error (struct super_block * sb, const char * function, const char * fmt, ...) { va_list args; - struct ext2_super_block *es = EXT2_SB(sb)->s_es; if (!(sb->s_flags & MS_RDONLY)) { sb->u.ext2_sb.s_mount_state |= EXT2_ERROR_FS; - es->s_state = - cpu_to_le16(le16_to_cpu(es->s_state) | EXT2_ERROR_FS); - ext2_sync_super(sb, es); + sb->u.ext2_sb.s_es->s_state = + cpu_to_le16(le16_to_cpu(sb->u.ext2_sb.s_es->s_state) | EXT2_ERROR_FS); + mark_buffer_dirty(sb->u.ext2_sb.s_sbh); + sb->s_dirt = 1; } va_start (args, fmt); vsprintf (error_buf, fmt, args); @@ -126,10 +124,8 @@ void ext2_put_super (struct super_block * sb) int i; if (!(sb->s_flags & MS_RDONLY)) { - struct ext2_super_block *es = EXT2_SB(sb)->s_es; - - es->s_state = le16_to_cpu(EXT2_SB(sb)->s_mount_state); - ext2_sync_super(sb, es); + sb->u.ext2_sb.s_es->s_state = le16_to_cpu(sb->u.ext2_sb.s_mount_state); + mark_buffer_dirty(sb->u.ext2_sb.s_sbh); } db_count = EXT2_SB(sb)->s_gdb_count; for (i = 0; i < db_count; i++) @@ -309,10 +305,13 @@ static int ext2_setup_super (struct super_block * sb, (le32_to_cpu(es->s_lastcheck) + le32_to_cpu(es->s_checkinterval) <= CURRENT_TIME)) printk ("EXT2-fs warning: checktime reached, " "running e2fsck is recommended\n"); + es->s_state = cpu_to_le16(le16_to_cpu(es->s_state) & ~EXT2_VALID_FS); if (!(__s16) le16_to_cpu(es->s_max_mnt_count)) es->s_max_mnt_count = (__s16) cpu_to_le16(EXT2_DFL_MAX_MNT_COUNT); es->s_mnt_count=cpu_to_le16(le16_to_cpu(es->s_mnt_count) + 1); - ext2_write_super(sb); + es->s_mtime = cpu_to_le32(CURRENT_TIME); + mark_buffer_dirty(sb->u.ext2_sb.s_sbh); + sb->s_dirt = 1; if (test_opt (sb, DEBUG)) printk ("[EXT II FS %s, %s, bs=%lu, fs=%lu, gc=%lu, " "bpg=%lu, ipg=%lu, mo=%04lx]\n", @@ -433,6 +432,7 @@ struct super_block * ext2_read_super (struct super_block * sb, void * data, printk ("EXT2-fs: unable to set blocksize %d\n", blocksize); return NULL; } + sb->s_blocksize = blocksize; /* * If the superblock doesn't start on a sector boundary, @@ -444,7 +444,7 @@ struct super_block * ext2_read_super (struct super_block * sb, void * data, offset = (sb_block*BLOCK_SIZE) % blocksize; } - if (!(bh = bread (dev, logic_sb_block, blocksize))) { + if (!(bh = sb_bread(sb, logic_sb_block))) { printk ("EXT2-fs: unable to read superblock\n"); return NULL; } @@ -503,7 +503,7 @@ struct super_block * ext2_read_super (struct super_block * sb, void * data, logic_sb_block = (sb_block*BLOCK_SIZE) / blocksize; offset = (sb_block*BLOCK_SIZE) % blocksize; - bh = bread (dev, logic_sb_block, blocksize); + bh = sb_bread(sb, logic_sb_block); if(!bh) { printk("EXT2-fs: Couldn't read superblock on " "2nd try.\n"); @@ -607,8 +607,7 @@ struct super_block * ext2_read_super (struct super_block * sb, void * data, goto failed_mount; } for (i = 0; i < db_count; i++) { - sb->u.ext2_sb.s_group_desc[i] = bread (dev, logic_sb_block + i + 1, - sb->s_blocksize); + sb->u.ext2_sb.s_group_desc[i] = sb_bread(sb, logic_sb_block + i + 1); if (!sb->u.ext2_sb.s_group_desc[i]) { for (j = 0; j < i; j++) brelse (sb->u.ext2_sb.s_group_desc[j]); @@ -665,15 +664,6 @@ static void ext2_commit_super (struct super_block * sb, sb->s_dirt = 0; } -static void ext2_sync_super(struct super_block *sb, struct ext2_super_block *es) -{ - es->s_wtime = cpu_to_le32(CURRENT_TIME); - mark_buffer_dirty(EXT2_SB(sb)->s_sbh); - ll_rw_block(WRITE, 1, &EXT2_SB(sb)->s_sbh); - wait_on_buffer(EXT2_SB(sb)->s_sbh); - sb->s_dirt = 0; -} - /* * In the second extended file system, it is not necessary to * write the super block since we use a mapping of the @@ -692,14 +682,13 @@ void ext2_write_super (struct super_block * sb) if (!(sb->s_flags & MS_RDONLY)) { es = sb->u.ext2_sb.s_es; + ext2_debug ("setting valid to 0\n"); + if (le16_to_cpu(es->s_state) & EXT2_VALID_FS) { - ext2_debug ("setting valid to 0\n"); - es->s_state = cpu_to_le16(le16_to_cpu(es->s_state) & - ~EXT2_VALID_FS); + es->s_state = cpu_to_le16(le16_to_cpu(es->s_state) & ~EXT2_VALID_FS); es->s_mtime = cpu_to_le32(CURRENT_TIME); - ext2_sync_super(sb, es); - } else - ext2_commit_super (sb, es); + } + ext2_commit_super (sb, es); } sb->s_dirt = 0; } @@ -736,7 +725,11 @@ int ext2_remount (struct super_block * sb, int * flags, char * data) */ es->s_state = cpu_to_le16(sb->u.ext2_sb.s_mount_state); es->s_mtime = cpu_to_le32(CURRENT_TIME); - } else { + mark_buffer_dirty(sb->u.ext2_sb.s_sbh); + sb->s_dirt = 1; + ext2_commit_super (sb, es); + } + else { int ret; if ((ret = EXT2_HAS_RO_COMPAT_FEATURE(sb, ~EXT2_FEATURE_RO_COMPAT_SUPP))) { @@ -754,7 +747,6 @@ int ext2_remount (struct super_block * sb, int * flags, char * data) if (!ext2_setup_super (sb, es, 0)) sb->s_flags &= ~MS_RDONLY; } - ext2_sync_super(sb, es); return 0; } diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c index db676c005..f4f87da52 100644 --- a/fs/ext3/balloc.c +++ b/fs/ext3/balloc.c @@ -91,8 +91,7 @@ static int read_block_bitmap (struct super_block * sb, if (!gdp) goto error_out; retval = 0; - bh = bread (sb->s_dev, - le32_to_cpu(gdp->bg_block_bitmap), sb->s_blocksize); + bh = sb_bread(sb, le32_to_cpu(gdp->bg_block_bitmap)); if (!bh) { ext3_error (sb, "read_block_bitmap", "Cannot read block bitmap - " @@ -353,8 +352,7 @@ do_more: #ifdef CONFIG_JBD_DEBUG { struct buffer_head *debug_bh; - debug_bh = get_hash_table(sb->s_dev, block + i, - sb->s_blocksize); + debug_bh = sb_get_hash_table(sb, block + i); if (debug_bh) { BUFFER_TRACE(debug_bh, "Deleted!"); if (!bh2jh(bitmap_bh)->b_committed_data) @@ -702,7 +700,7 @@ got_block: struct buffer_head *debug_bh; /* Record bitmap buffer state in the newly allocated block */ - debug_bh = get_hash_table(sb->s_dev, tmp, sb->s_blocksize); + debug_bh = sb_get_hash_table(sb, tmp); if (debug_bh) { BUFFER_TRACE(debug_bh, "state when allocated"); BUFFER_TRACE2(debug_bh, bh, "bitmap state"); diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c index 088f79673..062ed9374 100644 --- a/fs/ext3/ialloc.c +++ b/fs/ext3/ialloc.c @@ -60,8 +60,7 @@ static int read_inode_bitmap (struct super_block * sb, retval = -EIO; goto error_out; } - bh = bread (sb->s_dev, - le32_to_cpu(gdp->bg_inode_bitmap), sb->s_blocksize); + bh = sb_bread(sb, le32_to_cpu(gdp->bg_inode_bitmap)); if (!bh) { ext3_error (sb, "read_inode_bitmap", "Cannot read inode bitmap - " diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index 658ccef60..bd2bcf61d 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c @@ -388,8 +388,7 @@ static int ext3_block_to_path(struct inode *inode, long i_block, int offsets[4]) static Indirect *ext3_get_branch(struct inode *inode, int depth, int *offsets, Indirect chain[4], int *err) { - kdev_t dev = inode->i_dev; - int blocksize = inode->i_sb->s_blocksize; + struct super_block *sb = inode->i_sb; Indirect *p = chain; struct buffer_head *bh; @@ -399,7 +398,7 @@ static Indirect *ext3_get_branch(struct inode *inode, int depth, int *offsets, if (!p->key) goto no_block; while (--depth) { - bh = bread(dev, le32_to_cpu(p->key), blocksize); + bh = sb_bread(sb, le32_to_cpu(p->key)); if (!bh) goto failure; /* Reader: pointers */ @@ -557,7 +556,7 @@ static int ext3_alloc_branch(handle_t *handle, struct inode *inode, * and set the pointer to new one, then send * parent to disk. */ - bh = getblk(inode->i_dev, parent, blocksize); + bh = sb_getblk(inode->i_sb, parent); branch[n].bh = bh; lock_buffer(bh); BUFFER_TRACE(bh, "call get_create_access"); @@ -858,8 +857,7 @@ struct buffer_head *ext3_getblk(handle_t *handle, struct inode * inode, *errp = ext3_get_block_handle(handle, inode, block, &dummy, create); if (!*errp && buffer_mapped(&dummy)) { struct buffer_head *bh; - bh = getblk(dummy.b_dev, dummy.b_blocknr, - inode->i_sb->s_blocksize); + bh = sb_getblk(inode->i_sb, dummy.b_blocknr); if (buffer_new(&dummy)) { J_ASSERT(create != 0); J_ASSERT(handle != 0); @@ -1576,9 +1574,6 @@ ext3_clear_blocks(handle_t *handle, struct inode *inode, struct buffer_head *bh, u32 *first, u32 *last) { u32 *p; - kdev_t dev = inode->i_sb->s_dev; - unsigned long blocksize = inode->i_sb->s_blocksize; - if (try_to_extend_transaction(handle, inode)) { if (bh) { BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata"); @@ -1604,7 +1599,7 @@ ext3_clear_blocks(handle_t *handle, struct inode *inode, struct buffer_head *bh, struct buffer_head *bh; *p = 0; - bh = get_hash_table(dev, nr, blocksize); + bh = sb_get_hash_table(inode->i_sb, nr); ext3_forget(handle, 0, inode, bh, nr); } } @@ -1717,7 +1712,7 @@ static void ext3_free_branches(handle_t *handle, struct inode *inode, continue; /* A hole */ /* Go read the buffer for the next level down */ - bh = bread(inode->i_dev, nr, inode->i_sb->s_blocksize); + bh = sb_bread(inode->i_sb, nr); /* * A read failure? Report error and clear slot @@ -2030,7 +2025,7 @@ int ext3_get_inode_loc (struct inode *inode, struct ext3_iloc *iloc) EXT3_INODE_SIZE(inode->i_sb); block = le32_to_cpu(gdp[desc].bg_inode_table) + (offset >> EXT3_BLOCK_SIZE_BITS(inode->i_sb)); - if (!(bh = bread (inode->i_dev, block, inode->i_sb->s_blocksize))) { + if (!(bh = sb_bread(inode->i_sb, block))) { ext3_error (inode->i_sb, "ext3_get_inode_loc", "unable to read inode block - " "inode=%lu, block=%lu", inode->i_ino, block); diff --git a/fs/ext3/super.c b/fs/ext3/super.c index fb2303ffc..b82521cad 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c @@ -925,6 +925,7 @@ struct super_block * ext3_read_super (struct super_block * sb, void * data, goto out_fail; } + sb->s_blocksize = blocksize; set_blocksize (dev, blocksize); /* @@ -936,7 +937,7 @@ struct super_block * ext3_read_super (struct super_block * sb, void * data, offset = (sb_block * EXT3_MIN_BLOCK_SIZE) % blocksize; } - if (!(bh = bread (dev, logic_sb_block, blocksize))) { + if (!(bh = sb_bread(sb, logic_sb_block))) { printk (KERN_ERR "EXT3-fs: unable to read superblock\n"); goto out_fail; } @@ -1009,7 +1010,7 @@ struct super_block * ext3_read_super (struct super_block * sb, void * data, set_blocksize (dev, sb->s_blocksize); logic_sb_block = (sb_block * EXT3_MIN_BLOCK_SIZE) / blocksize; offset = (sb_block * EXT3_MIN_BLOCK_SIZE) % blocksize; - bh = bread (dev, logic_sb_block, blocksize); + bh = sb_bread(sb, logic_sb_block); if (!bh) { printk(KERN_ERR "EXT3-fs: Can't read superblock on 2nd try.\n"); @@ -1093,8 +1094,7 @@ struct super_block * ext3_read_super (struct super_block * sb, void * data, goto failed_mount; } for (i = 0; i < db_count; i++) { - sbi->s_group_desc[i] = bread(dev, logic_sb_block + i + 1, - blocksize); + sbi->s_group_desc[i] = sb_bread(sb, logic_sb_block + i + 1); if (!sbi->s_group_desc[i]) { printk (KERN_ERR "EXT3-fs: " "can't read group descriptor %d\n", i); diff --git a/fs/fat/buffer.c b/fs/fat/buffer.c index d8a4d0bda..117d85b33 100644 --- a/fs/fat/buffer.c +++ b/fs/fat/buffer.c @@ -59,12 +59,12 @@ void fat_ll_rw_block ( struct buffer_head *default_fat_bread(struct super_block *sb, int block) { - return bread (sb->s_dev, block, sb->s_blocksize); + return sb_bread(sb, block); } struct buffer_head *default_fat_getblk(struct super_block *sb, int block) { - return getblk (sb->s_dev, block, sb->s_blocksize); + return sb_getblk(sb, block); } void default_fat_brelse(struct super_block *sb, struct buffer_head *bh) diff --git a/fs/fat/inode.c b/fs/fat/inode.c index bba65eff5..5bbebb08c 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -584,7 +584,7 @@ fat_read_super(struct super_block *sb, void *data, int silent, sb->s_blocksize = hard_blksize; set_blocksize(sb->s_dev, hard_blksize); - bh = bread(sb->s_dev, 0, sb->s_blocksize); + bh = sb_bread(sb, 0); if (bh == NULL) { printk("FAT: unable to read boot sector\n"); goto out_fail; @@ -656,7 +656,7 @@ fat_read_super(struct super_block *sb, void *data, int silent, (sbi->fsinfo_sector * logical_sector_size) % hard_blksize; fsinfo_bh = bh; if (fsinfo_block != 0) { - fsinfo_bh = bread(sb->s_dev, fsinfo_block, hard_blksize); + fsinfo_bh = sb_bread(sb, fsinfo_block); if (fsinfo_bh == NULL) { printk("FAT: bread failed, FSINFO block" " (blocknr = %d)\n", fsinfo_block); diff --git a/fs/freevxfs/vxfs_bmap.c b/fs/freevxfs/vxfs_bmap.c index 979bb3718..fb3eeeb9f 100644 --- a/fs/freevxfs/vxfs_bmap.c +++ b/fs/freevxfs/vxfs_bmap.c @@ -137,9 +137,8 @@ vxfs_bmap_indir(struct inode *ip, long indir, int size, long block) struct vxfs_typed *typ; int64_t off; - bp = bread(ip->i_dev, - indir + (i / VXFS_TYPED_PER_BLOCK(ip->i_sb)), - ip->i_sb->s_blocksize); + bp = sb_bread(ip->i_sb, + indir + (i / VXFS_TYPED_PER_BLOCK(ip->i_sb))); if (!buffer_mapped(bp)) return 0; diff --git a/fs/freevxfs/vxfs_inode.c b/fs/freevxfs/vxfs_inode.c index a06f13f3b..363e1ac59 100644 --- a/fs/freevxfs/vxfs_inode.c +++ b/fs/freevxfs/vxfs_inode.c @@ -104,7 +104,7 @@ vxfs_blkiget(struct super_block *sbp, u_long extent, ino_t ino) block = extent + ((ino * VXFS_ISIZE) / sbp->s_blocksize); offset = ((ino % (sbp->s_blocksize / VXFS_ISIZE)) * VXFS_ISIZE); - bp = bread(sbp->s_dev, block, sbp->s_blocksize); + bp = sb_bread(sbp, block); if (buffer_mapped(bp)) { struct vxfs_inode_info *vip; diff --git a/fs/freevxfs/vxfs_subr.c b/fs/freevxfs/vxfs_subr.c index 7fe6688ec..341d5c1a7 100644 --- a/fs/freevxfs/vxfs_subr.c +++ b/fs/freevxfs/vxfs_subr.c @@ -114,7 +114,7 @@ vxfs_bread(struct inode *ip, int block) daddr_t pblock; pblock = vxfs_bmap1(ip, block); - bp = bread(ip->i_dev, pblock, ip->i_sb->s_blocksize); + bp = sb_bread(ip->i_sb, pblock); return (bp); } @@ -135,7 +135,7 @@ vxfs_bread(struct inode *ip, int block) * Zero on success, else a negativ error code (-EIO). */ static int -vxfs_getblk(struct inode *ip, long iblock, +vxfs_getblk(struct inode *ip, sector_t iblock, struct buffer_head *bp, int create) { daddr_t pblock; diff --git a/fs/hfs/file.c b/fs/hfs/file.c index fbfdc1b12..d2043ae51 100644 --- a/fs/hfs/file.c +++ b/fs/hfs/file.c @@ -61,7 +61,7 @@ struct inode_operations hfs_file_inode_operations = { struct buffer_head *hfs_getblk(struct hfs_fork *fork, int block, int create) { int tmp; - kdev_t dev = fork->entry->mdb->sys_mdb->s_dev; + struct super_block *sb = fork->entry->mdb->sys_mdb; tmp = hfs_extent_map(fork, block, create); @@ -71,7 +71,7 @@ struct buffer_head *hfs_getblk(struct hfs_fork *fork, int block, int create) */ if (tmp) { hfs_cat_mark_dirty(fork->entry); - return getblk(dev, tmp, HFS_SECTOR_SIZE); + return sb_getblk(sb, tmp); } return NULL; } else { @@ -80,8 +80,7 @@ struct buffer_head *hfs_getblk(struct hfs_fork *fork, int block, int create) we waited on the I/O in getblk to complete. */ do { - struct buffer_head *bh = - getblk(dev, tmp, HFS_SECTOR_SIZE); + struct buffer_head *bh = sb_getblk(sb, tmp); int tmp2 = hfs_extent_map(fork, block, 0); if (tmp2 == tmp) { @@ -107,7 +106,7 @@ struct buffer_head *hfs_getblk(struct hfs_fork *fork, int block, int create) * block number. This function just calls hfs_extent_map() to do the * real work and then stuffs the appropriate info into the buffer_head. */ -int hfs_get_block(struct inode *inode, long iblock, struct buffer_head *bh_result, int create) +int hfs_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create) { unsigned long phys; diff --git a/fs/hfs/hfs.h b/fs/hfs/hfs.h index f266bc0c4..e328a14ae 100644 --- a/fs/hfs/hfs.h +++ b/fs/hfs/hfs.h @@ -495,7 +495,7 @@ extern void hfs_extent_adj(struct hfs_fork *); extern void hfs_extent_free(struct hfs_fork *); /* file.c */ -extern int hfs_get_block(struct inode *, long, struct buffer_head *, int); +extern int hfs_get_block(struct inode *, sector_t, struct buffer_head *, int); /* mdb.c */ extern struct hfs_mdb *hfs_mdb_get(hfs_sysmdb, int, hfs_s32); diff --git a/fs/hfs/super.c b/fs/hfs/super.c index a39710f09..6d69f71d3 100644 --- a/fs/hfs/super.c +++ b/fs/hfs/super.c @@ -402,6 +402,8 @@ struct super_block *hfs_read_super(struct super_block *s, void *data, /* set the device driver to 512-byte blocks */ set_blocksize(dev, HFS_SECTOR_SIZE); + s->s_blocksize_bits = HFS_SECTOR_SIZE_BITS; + s->s_blocksize = HFS_SECTOR_SIZE; #ifdef CONFIG_MAC_PARTITION /* check to see if we're in a partition */ @@ -437,8 +439,6 @@ struct super_block *hfs_read_super(struct super_block *s, void *data, } s->s_magic = HFS_SUPER_MAGIC; - s->s_blocksize_bits = HFS_SECTOR_SIZE_BITS; - s->s_blocksize = HFS_SECTOR_SIZE; s->s_op = &hfs_super_operations; /* try to get the root inode */ diff --git a/fs/hfs/sysdep.c b/fs/hfs/sysdep.c index 4ce747a49..c96107d5f 100644 --- a/fs/hfs/sysdep.c +++ b/fs/hfs/sysdep.c @@ -41,9 +41,9 @@ hfs_buffer hfs_buffer_get(hfs_sysmdb sys_mdb, int block, int read) { hfs_buffer tmp = HFS_BAD_BUFFER; if (read) { - tmp = bread(sys_mdb->s_dev, block, HFS_SECTOR_SIZE); + tmp = sb_bread(sys_mdb, block); } else { - tmp = getblk(sys_mdb->s_dev, block, HFS_SECTOR_SIZE); + tmp = sb_getblk(sys_mdb, block); if (tmp) { mark_buffer_uptodate(tmp, 1); } diff --git a/fs/hpfs/buffer.c b/fs/hpfs/buffer.c index c7b63f358..66067c2a5 100644 --- a/fs/hpfs/buffer.c +++ b/fs/hpfs/buffer.c @@ -122,12 +122,9 @@ void hpfs_unlock_3inodes(struct inode *i1, struct inode *i2, struct inode *i3) void *hpfs_map_sector(struct super_block *s, unsigned secno, struct buffer_head **bhp, int ahead) { - kdev_t dev = s->s_dev; struct buffer_head *bh; - if (!ahead || secno + ahead >= s->s_hpfs_fs_size) - *bhp = bh = bread(dev, secno, 512); - else *bhp = bh = bread(dev, secno, 512); + *bhp = bh = sb_bread(s, secno); if (bh != NULL) return bh->b_data; else { @@ -143,7 +140,7 @@ void *hpfs_get_sector(struct super_block *s, unsigned secno, struct buffer_head struct buffer_head *bh; /*return hpfs_map_sector(s, secno, bhp, 0);*/ - if ((*bhp = bh = getblk(s->s_dev, secno, 512)) != NULL) { + if ((*bhp = bh = sb_getblk(s, secno)) != NULL) { if (!buffer_uptodate(bh)) wait_on_buffer(bh); mark_buffer_uptodate(bh, 1); return bh->b_data; @@ -158,7 +155,6 @@ void *hpfs_get_sector(struct super_block *s, unsigned secno, struct buffer_head void *hpfs_map_4sectors(struct super_block *s, unsigned secno, struct quad_buffer_head *qbh, int ahead) { - kdev_t dev = s->s_dev; struct buffer_head *bh; char *data; @@ -173,24 +169,22 @@ void *hpfs_map_4sectors(struct super_block *s, unsigned secno, struct quad_buffe goto bail; } - if (!ahead || secno + 4 + ahead > s->s_hpfs_fs_size) - qbh->bh[0] = bh = bread(dev, secno, 512); - else qbh->bh[0] = bh = bread(dev, secno, 512); + qbh->bh[0] = bh = sb_bread(s, secno); if (!bh) goto bail0; memcpy(data, bh->b_data, 512); - qbh->bh[1] = bh = bread(dev, secno + 1, 512); + qbh->bh[1] = bh = sb_bread(s, secno + 1); if (!bh) goto bail1; memcpy(data + 512, bh->b_data, 512); - qbh->bh[2] = bh = bread(dev, secno + 2, 512); + qbh->bh[2] = bh = sb_bread(s, secno + 2); if (!bh) goto bail2; memcpy(data + 2 * 512, bh->b_data, 512); - qbh->bh[3] = bh = bread(dev, secno + 3, 512); + qbh->bh[3] = bh = sb_bread(s, secno + 3); if (!bh) goto bail3; memcpy(data + 3 * 512, bh->b_data, 512); diff --git a/fs/isofs/dir.c b/fs/isofs/dir.c index 48a358de8..29db6b6c0 100644 --- a/fs/isofs/dir.c +++ b/fs/isofs/dir.c @@ -123,7 +123,7 @@ static int do_isofs_readdir(struct inode *inode, struct file *filp, int de_len; if (!bh) { - bh = isofs_bread(inode, bufsize, block); + bh = isofs_bread(inode, block); if (!bh) return 0; } @@ -158,7 +158,7 @@ static int do_isofs_readdir(struct inode *inode, struct file *filp, brelse(bh); bh = NULL; if (offset) { - bh = isofs_bread(inode, bufsize, block); + bh = isofs_bread(inode, block); if (!bh) return 0; memcpy((void *) tmpde + slop, bh->b_data, offset); diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index 305bf8fae..cbf4cabc3 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c @@ -527,6 +527,7 @@ static struct super_block *isofs_read_super(struct super_block *s, void *data, } set_blocksize(dev, opt.blocksize); + s->s_blocksize = opt.blocksize; s->u.isofs_sb.s_high_sierra = high_sierra = 0; /* default is iso9660 */ @@ -540,8 +541,8 @@ static struct super_block *isofs_read_super(struct super_block *s, void *data, struct iso_volume_descriptor * vdp; block = iso_blknum << (ISOFS_BLOCK_BITS-blocksize_bits); - if (!(bh = bread(dev, block, opt.blocksize))) - goto out_no_read; + if (!(bh = sb_bread(s, block))) + goto out_no_read; vdp = (struct iso_volume_descriptor *)bh->b_data; hdp = (struct hs_volume_descriptor *)bh->b_data; @@ -896,7 +897,6 @@ int isofs_get_blocks(struct inode *inode, sector_t iblock, unsigned int firstext; unsigned long nextino; int section, rv; - unsigned int blocksize = inode->i_sb->s_blocksize; lock_kernel(); @@ -957,7 +957,7 @@ int isofs_get_blocks(struct inode *inode, sector_t iblock, (*bh_result)->b_blocknr = firstext + b_off - offset; (*bh_result)->b_state |= (1UL << BH_Mapped); } else { - *bh_result = getblk(inode->i_dev, firstext+b_off-offset, blocksize); + *bh_result = sb_getblk(inode->i_sb, firstext+b_off-offset); if ( !*bh_result ) goto abort; } @@ -1000,12 +1000,12 @@ static int isofs_bmap(struct inode *inode, int block) return 0; } -struct buffer_head *isofs_bread(struct inode *inode, unsigned int bufsize, unsigned int block) +struct buffer_head *isofs_bread(struct inode *inode, unsigned int block) { unsigned int blknr = isofs_bmap(inode, block); if (!blknr) return NULL; - return bread(inode->i_dev, blknr, bufsize); + return sb_bread(inode->i_sb, blknr); } static int isofs_readpage(struct file *file, struct page *page) @@ -1060,7 +1060,7 @@ static int isofs_read_level3_size(struct inode * inode) unsigned int de_len; if (!bh) { - bh = bread(inode->i_dev, block, bufsize); + bh = sb_bread(inode->i_sb, block); if (!bh) goto out_noread; } @@ -1092,7 +1092,7 @@ static int isofs_read_level3_size(struct inode * inode) brelse(bh); bh = NULL; if (offset) { - bh = bread(inode->i_dev, block, bufsize); + bh = sb_bread(inode->i_sb, block); if (!bh) goto out_noread; memcpy((void *) tmpde + slop, bh->b_data, offset); @@ -1150,7 +1150,7 @@ static void isofs_read_inode(struct inode * inode) unsigned long offset; int volume_seq_no, i; - bh = bread(inode->i_dev, block, bufsize); + bh = sb_bread(inode->i_sb, block); if (!bh) goto out_badread; @@ -1168,7 +1168,7 @@ static void isofs_read_inode(struct inode * inode) } memcpy(tmpde, bh->b_data + offset, frag1); brelse(bh); - bh = bread(inode->i_dev, ++block, bufsize); + bh = sb_bread(inode->i_sb, ++block); if (!bh) goto out_badread; memcpy((char *)tmpde+frag1, bh->b_data, de_len - frag1); @@ -1345,7 +1345,7 @@ static void isofs_read_inode(struct inode * inode) #ifdef LEAK_CHECK #undef malloc #undef free_s -#undef bread +#undef sb_bread #undef brelse void * leak_check_malloc(unsigned int size){ @@ -1360,9 +1360,9 @@ void leak_check_free_s(void * obj, int size){ return kfree(obj); } -struct buffer_head * leak_check_bread(int dev, int block, int size){ +struct buffer_head * leak_check_bread(struct super_block *sb, int block){ check_bread++; - return bread(dev, block, size); + return sb_bread(sb, block); } void leak_check_brelse(struct buffer_head * bh){ diff --git a/fs/isofs/namei.c b/fs/isofs/namei.c index 87fe121f8..13e79d4d5 100644 --- a/fs/isofs/namei.c +++ b/fs/isofs/namei.c @@ -78,7 +78,7 @@ isofs_find_entry(struct inode *dir, struct dentry *dentry, char *dpnt; if (!bh) { - bh = isofs_bread(dir, bufsize, block); + bh = isofs_bread(dir, block); if (!bh) return 0; } @@ -108,7 +108,7 @@ isofs_find_entry(struct inode *dir, struct dentry *dentry, brelse(bh); bh = NULL; if (offset) { - bh = isofs_bread(dir, bufsize, block); + bh = isofs_bread(dir, block); if (!bh) return 0; memcpy((void *) tmpde + slop, bh->b_data, offset); diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c index ee1413f7b..6906a8eba 100644 --- a/fs/isofs/rock.c +++ b/fs/isofs/rock.c @@ -69,7 +69,7 @@ block = cont_extent; \ offset = cont_offset; \ offset1 = 0; \ - pbh = bread(DEV->i_dev, block, ISOFS_BUFFER_SIZE(DEV)); \ + pbh = sb_bread(DEV->i_sb, block); \ if(pbh){ \ memcpy(buffer + offset1, pbh->b_data + offset, cont_size - offset1); \ brelse(pbh); \ @@ -511,7 +511,7 @@ static int rock_ridge_symlink_readpage(struct file *file, struct page *page) block = inode->i_ino >> bufbits; lock_kernel(); - bh = bread(inode->i_dev, block, bufsize); + bh = sb_bread(inode->i_sb, block); if (!bh) goto out_noread; diff --git a/fs/minix/bitmap.c b/fs/minix/bitmap.c index 491a7fd5d..6347bb169 100644 --- a/fs/minix/bitmap.c +++ b/fs/minix/bitmap.c @@ -133,7 +133,7 @@ minix_V1_raw_inode(struct super_block *sb, ino_t ino, struct buffer_head **bh) ino--; block = 2 + sbi->s_imap_blocks + sbi->s_zmap_blocks + ino / MINIX_INODES_PER_BLOCK; - *bh = bread(sb->s_dev, block, BLOCK_SIZE); + *bh = sb_bread(sb, block); if (!*bh) { printk("unable to read i-node block\n"); return NULL; @@ -158,7 +158,7 @@ minix_V2_raw_inode(struct super_block *sb, ino_t ino, struct buffer_head **bh) ino--; block = 2 + sbi->s_imap_blocks + sbi->s_zmap_blocks + ino / MINIX2_INODES_PER_BLOCK; - *bh = bread(sb->s_dev, block, BLOCK_SIZE); + *bh = sb_bread(sb, block); if (!*bh) { printk("unable to read i-node block\n"); return NULL; diff --git a/fs/minix/inode.c b/fs/minix/inode.c index fe53b4991..5525a48a9 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c @@ -143,15 +143,15 @@ static struct super_block *minix_read_super(struct super_block *s, void *data, goto out_bad_hblock; set_blocksize(dev, BLOCK_SIZE); - if (!(bh = bread(dev,1,BLOCK_SIZE))) + s->s_blocksize = BLOCK_SIZE; + s->s_blocksize_bits = BLOCK_SIZE_BITS; + if (!(bh = sb_bread(s, 1))) goto out_bad_sb; ms = (struct minix_super_block *) bh->b_data; sbi->s_ms = ms; sbi->s_sbh = bh; sbi->s_mount_state = ms->s_state; - s->s_blocksize = BLOCK_SIZE; - s->s_blocksize_bits = BLOCK_SIZE_BITS; sbi->s_ninodes = ms->s_ninodes; sbi->s_nzones = ms->s_nzones; sbi->s_imap_blocks = ms->s_imap_blocks; @@ -198,12 +198,12 @@ static struct super_block *minix_read_super(struct super_block *s, void *data, block=2; for (i=0 ; i < sbi->s_imap_blocks ; i++) { - if (!(sbi->s_imap[i]=bread(dev,block,BLOCK_SIZE))) + if (!(sbi->s_imap[i]=sb_bread(s, block))) goto out_no_bitmap; block++; } for (i=0 ; i < sbi->s_zmap_blocks ; i++) { - if (!(sbi->s_zmap[i]=bread(dev,block,BLOCK_SIZE))) + if (!(sbi->s_zmap[i]=sb_bread(s, block))) goto out_no_bitmap; block++; } diff --git a/fs/minix/itree_common.c b/fs/minix/itree_common.c index 0aee59b47..373df9896 100644 --- a/fs/minix/itree_common.c +++ b/fs/minix/itree_common.c @@ -30,7 +30,7 @@ static inline Indirect *get_branch(struct inode *inode, Indirect chain[DEPTH], int *err) { - kdev_t dev = inode->i_dev; + struct super_block *sb = inode->i_sb; Indirect *p = chain; struct buffer_head *bh; @@ -40,7 +40,7 @@ static inline Indirect *get_branch(struct inode *inode, if (!p->key) goto no_block; while (--depth) { - bh = bread(dev, block_to_cpu(p->key), BLOCK_SIZE); + bh = sb_bread(sb, block_to_cpu(p->key)); if (!bh) goto failure; /* Reader: pointers */ @@ -79,7 +79,7 @@ static int alloc_branch(struct inode *inode, if (!nr) break; branch[n].key = cpu_to_block(nr); - bh = getblk(inode->i_dev, parent, BLOCK_SIZE); + bh = sb_getblk(inode->i_sb, parent); lock_buffer(bh); memset(bh->b_data, 0, BLOCK_SIZE); branch[n].bh = bh; @@ -277,7 +277,7 @@ static void free_branches(struct inode *inode, block_t *p, block_t *q, int depth if (!nr) continue; *p = 0; - bh = bread (inode->i_dev, nr, BLOCK_SIZE); + bh = sb_bread(inode->i_sb, nr); if (!bh) continue; free_branches(inode, (block_t*)bh->b_data, diff --git a/fs/namespace.c b/fs/namespace.c index d790be367..bbe12582a 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -517,9 +517,11 @@ static int do_loopback(struct nameidata *nd, char *old_name, int recurse) if (mnt) { err = graft_tree(mnt, nd); - if (err) + if (err) { + spin_lock(&dcache_lock); umount_tree(mnt); - else + spin_unlock(&dcache_lock); + } else mntput(mnt); } diff --git a/fs/ntfs/fs.c b/fs/ntfs/fs.c index 4533c63dc..5076c1dac 100644 --- a/fs/ntfs/fs.c +++ b/fs/ntfs/fs.c @@ -1023,8 +1023,9 @@ struct super_block *ntfs_read_super(struct super_block *sb, void *options, ntfs_error("Unable to set blocksize %d.\n", blocksize); goto ntfs_read_super_vol; } + sb->s_blocksize = blocksize; /* Read the super block (boot block). */ - if (!(bh = bread(sb->s_dev, 0, blocksize))) { + if (!(bh = sb_bread(sb, 0))) { ntfs_error("Reading super block failed\n"); goto ntfs_read_super_unl; } @@ -1071,8 +1072,7 @@ struct super_block *ntfs_read_super(struct super_block *sb, void *options, if (to_read < 1) to_read = 1; for (i = 0; i < to_read; i++) { - if (!(bh = bread(sb->s_dev, vol->mft_lcn + i, - vol->cluster_size))) { + if (!(bh = sb_bread(sb, vol->mft_lcn + i))) { ntfs_error("Could not read $Mft record 0\n"); goto ntfs_read_super_mft; } diff --git a/fs/ntfs/support.c b/fs/ntfs/support.c index 2f290b4de..d490f2553 100644 --- a/fs/ntfs/support.c +++ b/fs/ntfs/support.c @@ -169,7 +169,7 @@ int ntfs_getput_clusters(ntfs_volume *vol, int cluster, ntfs_size_t start_offs, buf->do_read ? "get" : "put", cluster, start_offs, length); to_copy = vol->cluster_size - start_offs; while (length) { - if (!(bh = bread(sb->s_dev, cluster, vol->cluster_size))) { + if (!(bh = sb_bread(sb, cluster))) { ntfs_debug(DEBUG_OTHER, "%s failed\n", buf->do_read ? "Reading" : "Writing"); error = -EIO; diff --git a/fs/qnx4/bitmap.c b/fs/qnx4/bitmap.c index 09b94399a..f544a436c 100644 --- a/fs/qnx4/bitmap.c +++ b/fs/qnx4/bitmap.c @@ -69,7 +69,7 @@ unsigned long qnx4_count_free_blocks(struct super_block *sb) struct buffer_head *bh; while (total < size) { - if ((bh = bread(sb->s_dev, start + offset, QNX4_BLOCK_SIZE)) == NULL) { + if ((bh = sb_bread(sb, start + offset)) == NULL) { printk("qnx4: I/O error in counting free blocks\n"); break; } @@ -96,7 +96,7 @@ int qnx4_is_free(struct super_block *sb, long block) QNX4DEBUG(("qnx4: is_free requesting block [%lu], bitmap in block [%lu]\n", (unsigned long) block, (unsigned long) start)); (void) size; /* CHECKME */ - bh = bread(sb->s_dev, start, QNX4_BLOCK_SIZE); + bh = sb_bread(sb, start); if (bh == NULL) { return -EIO; } @@ -124,7 +124,7 @@ int qnx4_set_bitmap(struct super_block *sb, long block, int busy) QNX4DEBUG(("qnx4: set_bitmap requesting block [%lu], bitmap in block [%lu]\n", (unsigned long) block, (unsigned long) start)); (void) size; /* CHECKME */ - bh = bread(sb->s_dev, start, QNX4_BLOCK_SIZE); + bh = sb_bread(sb, start); if (bh == NULL) { return -EIO; } diff --git a/fs/qnx4/dir.c b/fs/qnx4/dir.c index ac5d09b91..49df47d8f 100644 --- a/fs/qnx4/dir.c +++ b/fs/qnx4/dir.c @@ -36,7 +36,7 @@ static int qnx4_readdir(struct file *filp, void *dirent, filldir_t filldir) while (filp->f_pos < inode->i_size) { blknum = qnx4_block_map( inode, filp->f_pos >> QNX4_BLOCK_SIZE_BITS ); - bh = bread(inode->i_dev, blknum, QNX4_BLOCK_SIZE); + bh = sb_bread(inode->i_sb, blknum); if(bh==NULL) { printk(KERN_ERR "qnx4_readdir: bread failed (%ld)\n", blknum); break; diff --git a/fs/qnx4/fsync.c b/fs/qnx4/fsync.c index 26c8d7792..4ef5de955 100644 --- a/fs/qnx4/fsync.c +++ b/fs/qnx4/fsync.c @@ -24,8 +24,6 @@ #include <asm/segment.h> #include <asm/system.h> -#define blocksize QNX4_BLOCK_SIZE - /* * The functions for qnx4 fs file synchronization. */ @@ -40,7 +38,7 @@ static int sync_block(struct inode *inode, unsigned short *block, int wait) if (!*block) return 0; tmp = *block; - bh = get_hash_table(inode->i_dev, *block, blocksize); + bh = sb_get_hash_table(inode->i_sb, *block); if (!bh) return 0; if (*block != tmp) { @@ -74,7 +72,7 @@ static int sync_iblock(struct inode *inode, unsigned short *iblock, rc = sync_block(inode, iblock, wait); if (rc) return rc; - *bh = bread(inode->i_dev, tmp, blocksize); + *bh = sb_bread(inode->i_sb, tmp); if (tmp != *iblock) { brelse(*bh); *bh = NULL; diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c index 75ad8a8f5..cfec8ede9 100644 --- a/fs/qnx4/inode.c +++ b/fs/qnx4/inode.c @@ -95,7 +95,7 @@ static void qnx4_write_inode(struct inode *inode, int unused) QNX4DEBUG(("qnx4: write inode 2.\n")); block = ino / QNX4_INODES_PER_BLOCK; lock_kernel(); - if (!(bh = bread(inode->i_dev, block, QNX4_BLOCK_SIZE))) { + if (!(bh = sb_bread(inode->i_sb, block))) { printk("qnx4: major problem: unable to read inode from dev " "%s\n", kdevname(inode->i_dev)); unlock_kernel(); @@ -162,7 +162,7 @@ struct buffer_head *qnx4_getblk(struct inode *inode, int nr, if ( nr >= 0 ) nr = qnx4_block_map( inode, nr ); if (nr) { - result = getblk(inode->i_dev, nr, QNX4_BLOCK_SIZE); + result = sb_getblk(inode->i_sb, nr); return result; } if (!create) { @@ -173,7 +173,7 @@ struct buffer_head *qnx4_getblk(struct inode *inode, int nr, if (!tmp) { return NULL; } - result = getblk(inode->i_dev, tmp, QNX4_BLOCK_SIZE); + result = sb_getblk(inode->i_sb, tmp); if (tst) { qnx4_free_block(inode->i_sb, tmp); brelse(result); @@ -204,7 +204,7 @@ struct buffer_head *qnx4_bread(struct inode *inode, int block, int create) return NULL; } -int qnx4_get_block( struct inode *inode, long iblock, struct buffer_head *bh, int create ) +int qnx4_get_block( struct inode *inode, sector_t iblock, struct buffer_head *bh, int create ) { unsigned long phys; @@ -243,7 +243,7 @@ unsigned long qnx4_block_map( struct inode *inode, long iblock ) while ( --nxtnt > 0 ) { if ( ix == 0 ) { // read next xtnt block. - bh = bread( inode->i_dev, i_xblk - 1, QNX4_BLOCK_SIZE ); + bh = sb_bread(inode->i_sb, i_xblk - 1); if ( !bh ) { QNX4DEBUG(("qnx4: I/O error reading xtnt block [%ld])\n", i_xblk - 1)); return -EIO; @@ -307,7 +307,7 @@ static const char *qnx4_checkroot(struct super_block *sb) rd = le32_to_cpu(sb->u.qnx4_sb.sb->RootDir.di_first_xtnt.xtnt_blk) - 1; rl = le32_to_cpu(sb->u.qnx4_sb.sb->RootDir.di_first_xtnt.xtnt_size); for (j = 0; j < rl; j++) { - bh = bread(sb->s_dev, rd + j, QNX4_BLOCK_SIZE); /* root dir, first block */ + bh = sb_bread(sb, rd + j); /* root dir, first block */ if (bh == NULL) { return "unable to read root entry."; } @@ -350,7 +350,7 @@ static struct super_block *qnx4_read_super(struct super_block *s, /* Check the boot signature. Since the qnx4 code is dangerous, we should leave as quickly as possible if we don't belong here... */ - bh = bread(dev, 0, QNX4_BLOCK_SIZE); + bh = sb_bread(s, 0); if (!bh) { printk("qnx4: unable to read the boot sector\n"); goto outnobh; @@ -362,7 +362,7 @@ static struct super_block *qnx4_read_super(struct super_block *s, } brelse(bh); - bh = bread(dev, 1, QNX4_BLOCK_SIZE); + bh = sb_bread(s, 1); if (!bh) { printk("qnx4: unable to read the superblock\n"); goto outnobh; @@ -457,7 +457,7 @@ static void qnx4_read_inode(struct inode *inode) } block = ino / QNX4_INODES_PER_BLOCK; - if (!(bh = bread(inode->i_dev, block, QNX4_BLOCK_SIZE))) { + if (!(bh = sb_bread(inode->i_sb, block))) { printk("qnx4: major problem: unable to read inode from dev " "%s\n", kdevname(inode->i_dev)); return; diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c index 528882de0..05afd10d9 100644 --- a/fs/reiserfs/bitmap.c +++ b/fs/reiserfs/bitmap.c @@ -84,7 +84,7 @@ static inline void get_bit_address (struct super_block * s, unsigned long block, to free a list of blocks at once. -Hans */ /* I wonder if it would be less modest now that we use journaling. -Hans */ -static void _reiserfs_free_block (struct reiserfs_transaction_handle *th, unsigned long block) +void reiserfs_free_block (struct reiserfs_transaction_handle *th, unsigned long block) { struct super_block * s = th->t_super; struct reiserfs_super_block * rs; @@ -92,6 +92,9 @@ static void _reiserfs_free_block (struct reiserfs_transaction_handle *th, unsign struct buffer_head ** apbh; int nr, offset; + RFALSE(!s, "vs-4060: trying to free block on nonexistent device"); + RFALSE(is_reusable (s, block, 1) == 0, "vs-4070: can not free such block"); + PROC_INFO_INC( s, free_block ); rs = SB_DISK_SUPER_BLOCK (s); @@ -100,12 +103,8 @@ static void _reiserfs_free_block (struct reiserfs_transaction_handle *th, unsign get_bit_address (s, block, &nr, &offset); - if (nr >= sb_bmap_nr (rs)) { - reiserfs_warning ("vs-4075: reiserfs_free_block: " - "block %lu is out of range on %s\n", - block, bdevname(s->s_dev)); - return; - } + /* mark it before we clear it, just in case */ + journal_mark_freed(th, s, block) ; reiserfs_prepare_for_journal(s, apbh[nr], 1 ) ; @@ -125,26 +124,7 @@ static void _reiserfs_free_block (struct reiserfs_transaction_handle *th, unsign s->s_dirt = 1; } -void reiserfs_free_block (struct reiserfs_transaction_handle *th, - unsigned long block) { - struct super_block * s = th->t_super; - - RFALSE(!s, "vs-4061: trying to free block on nonexistent device"); - RFALSE(is_reusable (s, block, 1) == 0, "vs-4071: can not free such block"); - /* mark it before we clear it, just in case */ - journal_mark_freed(th, s, block) ; - _reiserfs_free_block(th, block) ; -} - -/* preallocated blocks don't need to be run through journal_mark_freed */ -void reiserfs_free_prealloc_block (struct reiserfs_transaction_handle *th, - unsigned long block) { - struct super_block * s = th->t_super; - RFALSE(!s, "vs-4060: trying to free block on nonexistent device"); - RFALSE(is_reusable (s, block, 1) == 0, "vs-4070: can not free such block"); - _reiserfs_free_block(th, block) ; -} /* beginning from offset-th bit in bmap_nr-th bitmap block, find_forward finds the closest zero bit. It returns 1 and zero @@ -422,6 +402,7 @@ free_and_return: ** has allocated it. loop around and try again */ if (reiserfs_test_and_set_le_bit (j, SB_AP_BITMAP (s)[i]->b_data)) { + reiserfs_warning("vs-4150: reiserfs_new_blocknrs, block not free"); reiserfs_restore_prepared_buffer(s, SB_AP_BITMAP(s)[i]) ; amount_needed++ ; continue ; @@ -507,7 +488,12 @@ int reiserfs_new_unf_blocknrs2 (struct reiserfs_transaction_handle *th, ** to be grouped towards the start of the border */ border = le32_to_cpu(INODE_PKEY(p_s_inode)->k_dir_id) % (SB_BLOCK_COUNT(th->t_super) - bstart - 1) ; - } else if (!reiserfs_hashed_relocation(th->t_super)) { + } else { + /* why would we want to delcare a local variable to this if statement + ** name border????? -chris + ** unsigned long border = 0; + */ + if (!reiserfs_hashed_relocation(th->t_super)) { hash_in = le32_to_cpu((INODE_PKEY(p_s_inode))->k_dir_id); /* I wonder if the CPU cost of the hash will obscure the layout @@ -517,6 +503,7 @@ int reiserfs_new_unf_blocknrs2 (struct reiserfs_transaction_handle *th, hash_out = keyed_hash(((char *) (&hash_in)), 4); border = hash_out % (SB_BLOCK_COUNT(th->t_super) - bstart - 1) ; + } } border += bstart ; allocated[0] = 0 ; /* important. Allows a check later on to see if at @@ -672,13 +659,11 @@ int reiserfs_new_unf_blocknrs2 (struct reiserfs_transaction_handle *th, static void __discard_prealloc (struct reiserfs_transaction_handle * th, struct inode * inode) { - unsigned long save = inode->u.reiserfs_i.i_prealloc_block ; while (inode->u.reiserfs_i.i_prealloc_count > 0) { - reiserfs_free_prealloc_block(th,inode->u.reiserfs_i.i_prealloc_block); + reiserfs_free_block(th,inode->u.reiserfs_i.i_prealloc_block); inode->u.reiserfs_i.i_prealloc_block++; inode->u.reiserfs_i.i_prealloc_count --; } - inode->u.reiserfs_i.i_prealloc_block = save ; list_del (&(inode->u.reiserfs_i.i_prealloc_list)); } diff --git a/fs/reiserfs/buffer2.c b/fs/reiserfs/buffer2.c index 367a4dcbf..26570b6d3 100644 --- a/fs/reiserfs/buffer2.c +++ b/fs/reiserfs/buffer2.c @@ -2,6 +2,15 @@ * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README */ + +/* + * Contains code from + * + * linux/include/linux/lock.h and linux/fs/buffer.c /linux/fs/minix/fsync.c + * + * Copyright (C) 1991, 1992 Linus Torvalds + */ + #include <linux/config.h> #include <linux/sched.h> #include <linux/locks.h> @@ -12,8 +21,12 @@ /* * wait_buffer_until_released * reiserfs_bread + * reiserfs_getblk + * get_new_buffer */ + + /* when we allocate a new block (get_new_buffer, get_empty_nodes) and get buffer for it, it is possible that it is held by someone else or even by this process. In this function we wait until all other @@ -34,6 +47,7 @@ void wait_buffer_until_released (const struct buffer_head * bh) } run_task_queue(&tq_disk); current->policy |= SCHED_YIELD; + /*current->counter = 0;*/ schedule(); } if (repeat_counter > 30000000) { @@ -49,6 +63,7 @@ void wait_buffer_until_released (const struct buffer_head * bh) then it creates a new buffer and schedules I/O to read the block. */ /* The function is NOT SCHEDULE-SAFE! */ + struct buffer_head * reiserfs_bread (struct super_block *super, int n_block, int n_size) { struct buffer_head *result; @@ -61,3 +76,276 @@ struct buffer_head * reiserfs_bread (struct super_block *super, int n_block, in return result; } +/* This function looks for a buffer which contains a given block. If + the block is in cache it returns it, otherwise it returns a new + buffer which is not uptodate. This is called by reiserfs_bread and + other functions. Note that get_new_buffer ought to be called this + and this ought to be called get_new_buffer, since this doesn't + actually get the block off of the disk. */ +/* The function is NOT SCHEDULE-SAFE! */ + +struct buffer_head * reiserfs_getblk (kdev_t n_dev, int n_block, int n_size) +{ + return getblk (n_dev, n_block, n_size); +} + +#ifdef NEW_GET_NEW_BUFFER + +/* returns one buffer with a blocknr near blocknr. */ +static int get_new_buffer_near_blocknr( + struct super_block * p_s_sb, + int blocknr, + struct buffer_head ** pp_s_new_bh, + struct path * p_s_path + ) { + unsigned long n_new_blocknumber = 0; + int n_ret_value, + n_repeat = CARRY_ON; + +#ifdef CONFIG_REISERFS_CHECK + int repeat_counter = 0; + + if (!blocknr) + printk ("blocknr passed to get_new_buffer_near_blocknr was 0"); +#endif + + + if ( (n_ret_value = reiserfs_new_blocknrs (p_s_sb, &n_new_blocknumber, + blocknr, 1)) == NO_DISK_SPACE ) + return NO_DISK_SPACE; + + *pp_s_new_bh = reiserfs_getblk(p_s_sb->s_dev, n_new_blocknumber, p_s_sb->s_blocksize); + if ( buffer_uptodate(*pp_s_new_bh) ) { + + RFALSE( buffer_dirty(*pp_s_new_bh) || (*pp_s_new_bh)->b_dev == NODEV, + "PAP-14080: invalid uptodate buffer %b for the new block", + *pp_s_new_bh); + + /* Free path buffers to prevent deadlock. */ + /* It is possible that this process has the buffer, which this function is getting, already in + its path, and is responsible for double incrementing the value of b_count. If we recalculate + the path after schedule we can avoid risking an endless loop. This problematic situation is + possible in a multiple processing environment. Suppose process 1 has acquired a path P; then + process 2 balanced and remove block A from the tree. Process 1 continues and runs + get_new_buffer, that returns buffer with block A. If node A was on the path P, then it will + have b_count == 2. If we now will simply wait in while ( (*pp_s_new_bh)->b_count > 1 ) we get + into an endless loop, as nobody will release this buffer and the current process holds buffer + twice. That is why we do decrement_counters_in_path(p_s_path) before waiting until b_count + becomes 1. (it there were other processes holding node A, then eventually we will get a + moment, when all of them released a buffer). */ + if ( atomic_read (&((*pp_s_new_bh)->b_count)) > 1 ) { + decrement_counters_in_path(p_s_path); + n_ret_value |= SCHEDULE_OCCURRED; + } + + while ( atomic_read (&((*pp_s_new_bh)->b_count)) > 1 ) { + +#ifdef REISERFS_INFO + printk("get_new_buffer() calls schedule to decrement b_count\n"); +#endif + +#ifdef CONFIG_REISERFS_CHECK + if ( ! (++repeat_counter % 10000) ) + printk("get_new_buffer(%u): counter(%d) too big", current->pid, repeat_counter); +#endif + + current->counter = 0; + schedule(); + } + +#ifdef CONFIG_REISERFS_CHECK + if ( buffer_dirty(*pp_s_new_bh) || (*pp_s_new_bh)->b_dev == NODEV ) { + print_buffer_head(*pp_s_new_bh,"get_new_buffer"); + reiserfs_panic(p_s_sb, "PAP-14090: get_new_buffer: invalid uptodate buffer %b for the new block(case 2)", *pp_s_new_bh); + } +#endif + + } + else { + ; + + RFALSE( atomic_read (&((*pp_s_new_bh)->b_count)) != 1, + "PAP-14100: not uptodate buffer %b for the new block has b_count more than one", + *pp_s_new_bh); + + } + return (n_ret_value | n_repeat); +} + + +/* returns the block number of the last unformatted node, assumes p_s_key_to_search.k_offset is a byte in the tail of + the file, Useful for when you want to append to a file, and convert a direct item into an unformatted node near the + last unformatted node of the file. Putting the unformatted node near the direct item is potentially very bad to do. + If there is no unformatted node in the file, then we return the block number of the direct item. */ +/* The function is NOT SCHEDULE-SAFE! */ +inline int get_last_unformatted_node_blocknr_of_file( struct key * p_s_key_to_search, struct super_block * p_s_sb, + struct buffer_head * p_s_bh + struct path * p_unf_search_path, struct inode * p_s_inode) + +{ + struct key unf_key_to_search; + struct item_head * p_s_ih; + int n_pos_in_item; + struct buffer_head * p_indirect_item_bh; + + copy_key(&unf_key_to_search,p_s_key_to_search); + unf_key_to_search.k_uniqueness = TYPE_INDIRECT; + unf_key_to_search.k_offset = p_s_inode->u.reiserfs_i.i_first_direct_byte - 1; + + /* p_s_key_to_search->k_offset - MAX_ITEM_LEN(p_s_sb->s_blocksize); */ + if (search_for_position_by_key (p_s_sb, &unf_key_to_search, p_unf_search_path, &n_pos_in_item) == POSITION_FOUND) + { + p_s_ih = B_N_PITEM_HEAD(p_indirect_item_bh = PATH_PLAST_BUFFER(p_unf_search_path), PATH_LAST_POSITION(p_unf_search_path)); + return (B_I_POS_UNFM_POINTER(p_indirect_item_bh, p_s_ih, n_pos_in_item)); + } + /* else */ + printk("reiser-1800: search for unformatted node failed, p_s_key_to_search->k_offset = %u, unf_key_to_search.k_offset = %u, MAX_ITEM_LEN(p_s_sb->s_blocksize) = %ld, debug this\n", p_s_key_to_search->k_offset, unf_key_to_search.k_offset, MAX_ITEM_LEN(p_s_sb->s_blocksize) ); + print_buffer_head(PATH_PLAST_BUFFER(p_unf_search_path), "the buffer holding the item before the key we failed to find"); + print_block_head(PATH_PLAST_BUFFER(p_unf_search_path), "the block head"); + return 0; /* keeps the compiler quiet */ +} + + + /* hasn't been out of disk space tested */ +/* The function is NOT SCHEDULE-SAFE! */ +static int get_buffer_near_last_unf ( struct super_block * p_s_sb, struct key * p_s_key_to_search, + struct inode * p_s_inode, struct buffer_head * p_s_bh, + struct buffer_head ** pp_s_un_bh, struct path * p_s_search_path) +{ + int unf_blocknr = 0, /* blocknr from which we start search for a free block for an unformatted node, if 0 + then we didn't find an unformatted node though we might have found a file hole */ + n_repeat = CARRY_ON; + struct key unf_key_to_search; + struct path unf_search_path; + + copy_key(&unf_key_to_search,p_s_key_to_search); + unf_key_to_search.k_uniqueness = TYPE_INDIRECT; + + if ( + (p_s_inode->u.reiserfs_i.i_first_direct_byte > 4095) /* i_first_direct_byte gets used for all sorts of + crap other than what the name indicates, thus + testing to see if it is 0 is not enough */ + && (p_s_inode->u.reiserfs_i.i_first_direct_byte < MAX_KEY_OFFSET) /* if there is no direct item then + i_first_direct_byte = MAX_KEY_OFFSET */ + ) + { + /* actually, we don't want the last unformatted node, we want the last unformatted node + which is before the current file offset */ + unf_key_to_search.k_offset = ((p_s_inode->u.reiserfs_i.i_first_direct_byte -1) < unf_key_to_search.k_offset) ? p_s_inode->u.reiserfs_i.i_first_direct_byte -1 : unf_key_to_search.k_offset; + + while (unf_key_to_search.k_offset > -1) + { + /* This is our poorly documented way of initializing paths. -Hans */ + init_path (&unf_search_path); + /* get the blocknr from which we start the search for a free block. */ + unf_blocknr = get_last_unformatted_node_blocknr_of_file( p_s_key_to_search, /* assumes this points to the file tail */ + p_s_sb, /* lets us figure out the block size */ + p_s_bh, /* if there is no unformatted node in the file, + then it returns p_s_bh->b_blocknr */ + &unf_search_path, + p_s_inode + ); +/* printk("in while loop: unf_blocknr = %d, *pp_s_un_bh = %p\n", unf_blocknr, *pp_s_un_bh); */ + if (unf_blocknr) + break; + else /* release the path and search again, this could be really slow for huge + holes.....better to spend the coding time adding compression though.... -Hans */ + { + /* Vladimir, is it a problem that I don't brelse these buffers ?-Hans */ + decrement_counters_in_path(&unf_search_path); + unf_key_to_search.k_offset -= 4096; + } + } + if (unf_blocknr) { + n_repeat |= get_new_buffer_near_blocknr(p_s_sb, unf_blocknr, pp_s_un_bh, p_s_search_path); + } + else { /* all unformatted nodes are holes */ + n_repeat |= get_new_buffer_near_blocknr(p_s_sb, p_s_bh->b_blocknr, pp_s_un_bh, p_s_search_path); + } + } + else { /* file has no unformatted nodes */ + n_repeat |= get_new_buffer_near_blocknr(p_s_sb, p_s_bh->b_blocknr, pp_s_un_bh, p_s_search_path); +/* printk("in else: unf_blocknr = %d, *pp_s_un_bh = %p\n", unf_blocknr, *pp_s_un_bh); */ +/* print_path (0, p_s_search_path); */ + } + + return n_repeat; +} + +#endif /* NEW_GET_NEW_BUFFER */ + + +#ifdef OLD_GET_NEW_BUFFER + +/* The function is NOT SCHEDULE-SAFE! */ +int get_new_buffer( + struct reiserfs_transaction_handle *th, + struct buffer_head * p_s_bh, + struct buffer_head ** pp_s_new_bh, + struct path * p_s_path + ) { + unsigned long n_new_blocknumber = 0; + int n_repeat; + struct super_block * p_s_sb = th->t_super; + + if ( (n_repeat = reiserfs_new_unf_blocknrs (th, &n_new_blocknumber, p_s_bh->b_blocknr)) == NO_DISK_SPACE ) + return NO_DISK_SPACE; + + *pp_s_new_bh = reiserfs_getblk(p_s_sb->s_dev, n_new_blocknumber, p_s_sb->s_blocksize); + if (atomic_read (&(*pp_s_new_bh)->b_count) > 1) { + /* Free path buffers to prevent deadlock which can occur in the + situation like : this process holds p_s_path; Block + (*pp_s_new_bh)->b_blocknr is on the path p_s_path, but it is + not necessary, that *pp_s_new_bh is in the tree; process 2 + could remove it from the tree and freed block + (*pp_s_new_bh)->b_blocknr. Reiserfs_new_blocknrs in above + returns block (*pp_s_new_bh)->b_blocknr. Reiserfs_getblk gets + buffer for it, and it has b_count > 1. If we now will simply + wait in while ( (*pp_s_new_bh)->b_count > 1 ) we get into an + endless loop, as nobody will release this buffer and the + current process holds buffer twice. That is why we do + decrement_counters_in_path(p_s_path) before waiting until + b_count becomes 1. (it there were other processes holding node + pp_s_new_bh, then eventually we will get a moment, when all of + them released a buffer). */ + decrement_counters_in_path(p_s_path); + wait_buffer_until_released (*pp_s_new_bh); + n_repeat |= SCHEDULE_OCCURRED; + } + + RFALSE( atomic_read (&((*pp_s_new_bh)->b_count)) != 1 || + buffer_dirty (*pp_s_new_bh), + "PAP-14100: not free or dirty buffer %b for the new block", + *pp_s_new_bh); + + return n_repeat; +} + +#endif /* OLD_GET_NEW_BUFFER */ + + +#ifdef GET_MANY_BLOCKNRS + /* code not yet functional */ +get_next_blocknr ( + unsigned long * p_blocknr_array, /* we get a whole bunch of blocknrs all at once for + the write. This is better than getting them one at + a time. */ + unsigned long ** p_blocknr_index, /* pointer to current offset into the array. */ + unsigned long blocknr_array_length +) +{ + unsigned long return_value; + + if (*p_blocknr_index < p_blocknr_array + blocknr_array_length) { + return_value = **p_blocknr_index; + **p_blocknr_index = 0; + *p_blocknr_index++; + return (return_value); + } + else + { + kfree (p_blocknr_array); + } +} +#endif /* GET_MANY_BLOCKNRS */ + diff --git a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c index ca9393ea5..228d97277 100644 --- a/fs/reiserfs/dir.c +++ b/fs/reiserfs/dir.c @@ -22,6 +22,22 @@ struct file_operations reiserfs_dir_operations = { fsync: reiserfs_dir_fsync, }; +/* + * directories can handle most operations... + */ +struct inode_operations reiserfs_dir_inode_operations = { + //&reiserfs_dir_operations, /* default_file_ops */ + create: reiserfs_create, + lookup: reiserfs_lookup, + link: reiserfs_link, + unlink: reiserfs_unlink, + symlink: reiserfs_symlink, + mkdir: reiserfs_mkdir, + rmdir: reiserfs_rmdir, + mknod: reiserfs_mknod, + rename: reiserfs_rename, +}; + int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry, int datasync) { lock_kernel(); reiserfs_commit_for_inode(dentry->d_inode) ; @@ -170,7 +186,7 @@ static int reiserfs_readdir (struct file * filp, void * dirent, filldir_t filldi } /* directory continues in the right neighboring block */ - set_cpu_key_k_offset (&pos_key, le_key_k_offset (KEY_FORMAT_3_5, rkey)); + set_cpu_key_k_offset (&pos_key, le_key_k_offset (ITEM_VERSION_1, rkey)); } /* while */ @@ -182,71 +198,3 @@ static int reiserfs_readdir (struct file * filp, void * dirent, filldir_t filldi reiserfs_check_path(&path_to_entry) ; return 0; } - -/* compose directory item containing "." and ".." entries (entries are - not aligned to 4 byte boundary) */ -/* the last four params are LE */ -void make_empty_dir_item_v1 (char * body, __u32 dirid, __u32 objid, - __u32 par_dirid, __u32 par_objid) -{ - struct reiserfs_de_head * deh; - - memset (body, 0, EMPTY_DIR_SIZE_V1); - deh = (struct reiserfs_de_head *)body; - - /* direntry header of "." */ - put_deh_offset( &(deh[0]), DOT_OFFSET ); - /* these two are from make_le_item_head, and are are LE */ - deh[0].deh_dir_id = dirid; - deh[0].deh_objectid = objid; - deh[0].deh_state = 0; /* Endian safe if 0 */ - put_deh_location( &(deh[0]), EMPTY_DIR_SIZE_V1 - strlen( "." )); - mark_de_visible(&(deh[0])); - - /* direntry header of ".." */ - put_deh_offset( &(deh[1]), DOT_DOT_OFFSET); - /* key of ".." for the root directory */ - /* these two are from the inode, and are are LE */ - deh[1].deh_dir_id = par_dirid; - deh[1].deh_objectid = par_objid; - deh[1].deh_state = 0; /* Endian safe if 0 */ - put_deh_location( &(deh[1]), deh_location( &(deh[0]) ) - strlen( ".." ) ); - mark_de_visible(&(deh[1])); - - /* copy ".." and "." */ - memcpy (body + deh_location( &(deh[0]) ), ".", 1); - memcpy (body + deh_location( &(deh[1]) ), "..", 2); -} - -/* compose directory item containing "." and ".." entries */ -void make_empty_dir_item (char * body, __u32 dirid, __u32 objid, - __u32 par_dirid, __u32 par_objid) -{ - struct reiserfs_de_head * deh; - - memset (body, 0, EMPTY_DIR_SIZE); - deh = (struct reiserfs_de_head *)body; - - /* direntry header of "." */ - put_deh_offset( &(deh[0]), DOT_OFFSET ); - /* these two are from make_le_item_head, and are are LE */ - deh[0].deh_dir_id = dirid; - deh[0].deh_objectid = objid; - deh[0].deh_state = 0; /* Endian safe if 0 */ - put_deh_location( &(deh[0]), EMPTY_DIR_SIZE - ROUND_UP( strlen( "." ) ) ); - mark_de_visible(&(deh[0])); - - /* direntry header of ".." */ - put_deh_offset( &(deh[1]), DOT_DOT_OFFSET ); - /* key of ".." for the root directory */ - /* these two are from the inode, and are are LE */ - deh[1].deh_dir_id = par_dirid; - deh[1].deh_objectid = par_objid; - deh[1].deh_state = 0; /* Endian safe if 0 */ - put_deh_location( &(deh[1]), deh_location( &(deh[0])) - ROUND_UP( strlen( ".." ) ) ); - mark_de_visible(&(deh[1])); - - /* copy ".." and "." */ - memcpy (body + deh_location( &(deh[0]) ), ".", 1); - memcpy (body + deh_location( &(deh[1]) ), "..", 2); -} diff --git a/fs/reiserfs/do_balan.c b/fs/reiserfs/do_balan.c index 1c9e1bca9..270917411 100644 --- a/fs/reiserfs/do_balan.c +++ b/fs/reiserfs/do_balan.c @@ -274,6 +274,13 @@ static int balance_leaf (struct tree_balance * tb, int pos_in_item; int zeros_num; +#if 0 + if (tb->insert_size [0] % 4) { + reiserfs_panic (tb->tb_sb, "balance_leaf: wrong insert_size %d", + tb->insert_size [0]); + } +#endif + PROC_INFO_INC( tb -> tb_sb, balance_at[ 0 ] ); /* Make balance in case insert_size[0] < 0 */ diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c index 739176d42..3a41dc5f4 100644 --- a/fs/reiserfs/file.c +++ b/fs/reiserfs/file.c @@ -33,7 +33,7 @@ static int reiserfs_file_release (struct inode * inode, struct file * filp) /* fast out for when nothing needs to be done */ if ((atomic_read(&inode->i_count) > 1 || - !(inode->u.reiserfs_i.i_flags & i_pack_on_close_mask) || + !inode->u.reiserfs_i.i_pack_on_close || !tail_has_to_be_packed(inode)) && inode->u.reiserfs_i.i_prealloc_count <= 0) { return 0; @@ -50,7 +50,7 @@ static int reiserfs_file_release (struct inode * inode, struct file * filp) journal_end(&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT * 3) ; if (atomic_read(&inode->i_count) <= 1 && - (inode->u.reiserfs_i.i_flags & i_pack_on_close_mask) && + inode->u.reiserfs_i.i_pack_on_close && tail_has_to_be_packed (inode)) { /* if regular file is released by last holder and it has been appended (we append by unformatted node only) or its direct @@ -97,17 +97,11 @@ static int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) { /* version 2 items will be caught by the s_maxbytes check ** done for us in vmtruncate */ - if (get_inode_item_key_version(inode) == KEY_FORMAT_3_5 && + if (inode_items_version(inode) == ITEM_VERSION_1 && attr->ia_size > MAX_NON_LFS) return -EFBIG ; } - if ((((attr->ia_valid & ATTR_UID) && (attr->ia_uid & ~0xffff)) || - ((attr->ia_valid & ATTR_GID) && (attr->ia_gid & ~0xffff))) && - (get_inode_sd_version (inode) == STAT_DATA_V1)) - /* stat data of format v3.5 has 16 bit uid and gid */ - return -EINVAL; - error = inode_change_ok(inode, attr) ; if (!error) inode_setattr(inode, attr) ; diff --git a/fs/reiserfs/fix_node.c b/fs/reiserfs/fix_node.c index 44f599bee..5f800a83b 100644 --- a/fs/reiserfs/fix_node.c +++ b/fs/reiserfs/fix_node.c @@ -806,7 +806,7 @@ static int get_empty_nodes( RFALSE( ! *p_n_blocknr, "PAP-8135: reiserfs_new_blocknrs failed when got new blocks"); - p_s_new_bh = getblk(p_s_sb->s_dev, *p_n_blocknr, p_s_sb->s_blocksize); + p_s_new_bh = reiserfs_getblk(p_s_sb->s_dev, *p_n_blocknr, p_s_sb->s_blocksize); if (atomic_read (&(p_s_new_bh->b_count)) > 1) { /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/ /* @@ -920,7 +920,7 @@ static int is_left_neighbor_in_cache( /* Get left neighbor block number. */ n_left_neighbor_blocknr = B_N_CHILD_NUM(p_s_tb->FL[n_h], n_left_neighbor_position); /* Look for the left neighbor in the cache. */ - if ( (left = get_hash_table(p_s_sb->s_dev, n_left_neighbor_blocknr, p_s_sb->s_blocksize)) ) { + if ( (left = sb_get_hash_table(p_s_sb, n_left_neighbor_blocknr)) ) { RFALSE( buffer_uptodate (left) && ! B_IS_IN_TREE(left), "vs-8170: left neighbor (%b %z) is not in the tree", left, left); @@ -2021,6 +2021,23 @@ static int get_virtual_node_size (struct super_block * sb, struct buffer_head * // entry would eat 2 byte of virtual node space return sb->s_blocksize; +#if 0 + size = sizeof (struct virtual_node) + sizeof (struct virtual_item); + ih = B_N_PITEM_HEAD (bh, 0); + nr_items = B_NR_ITEMS (bh); + for (i = 0; i < nr_items; i ++, ih ++) { + /* each item occupies some space in virtual node */ + size += sizeof (struct virtual_item); + if (is_direntry_le_ih (ih)) + /* each entry and new one occupeis 2 byte in the virtual node */ + size += (ih_entry_count(ih) + 1) * sizeof( __u16 ); + } + + /* 1 bit for each bitmap block to note whether bitmap block was + dirtied in the operation */ + /* size += (SB_BMAP_NR (sb) * 2 / 8 + 4);*/ + return size; +#endif } @@ -2326,6 +2343,15 @@ int fix_nodes (int n_op_mode, "at the beginning of fix_nodes or not in tree (mode %c)", p_s_tbS0, p_s_tbS0, n_op_mode); } + // FIXME: new items have to be of 8 byte multiples. Including new + // directory items those look like old ones + /* + if (p_s_tb->insert_size[0] % 8) + reiserfs_panic (p_s_tb->tb_sb, "vs-: fix_nodes: incorrect insert_size %d, " + "mode %c", + p_s_tb->insert_size[0], n_op_mode); + */ + /* Check parameters. */ switch (n_op_mode) { case M_INSERT: diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 421485049..65ac67889 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c @@ -1963,7 +1963,7 @@ int reiserfs_prepare_write(struct file *f, struct page *page, // // this is exactly what 2.3.99-pre9's ext2_bmap is // -static int reiserfs_aop_bmap(struct address_space *as, sector_t block) { +static int reiserfs_aop_bmap(struct address_space *as, long block) { return generic_block_bmap(as, block, reiserfs_bmap) ; } diff --git a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c index 95cb132ee..d142a322c 100644 --- a/fs/reiserfs/ioctl.c +++ b/fs/reiserfs/ioctl.c @@ -46,7 +46,7 @@ int reiserfs_unpack (struct inode * inode, struct file * filp) return -EINVAL ; } /* ioctl already done */ - if (inode->u.reiserfs_i.i_flags & i_nopack_mask) { + if (inode->u.reiserfs_i.nopack) { return 0 ; } lock_kernel(); @@ -59,7 +59,7 @@ int reiserfs_unpack (struct inode * inode, struct file * filp) write_from = inode->i_size & (blocksize - 1) ; /* if we are on a block boundary, we are already unpacked. */ if ( write_from == 0) { - inode->u.reiserfs_i.i_flags |= i_nopack_mask; + inode->u.reiserfs_i.nopack = 1; goto out ; } @@ -79,7 +79,7 @@ int reiserfs_unpack (struct inode * inode, struct file * filp) /* conversion can change page contents, must flush */ flush_dcache_page(page) ; - inode->u.reiserfs_i.i_flags |= i_nopack_mask; + inode->u.reiserfs_i.nopack = 1; kunmap(page) ; /* mapped by prepare_write */ out_unlock: diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c index 2c71fd471..3b70c989b 100644 --- a/fs/reiserfs/journal.c +++ b/fs/reiserfs/journal.c @@ -683,7 +683,7 @@ retry: count = 0 ; for (i = 0 ; atomic_read(&(jl->j_commit_left)) > 1 && i < (jl->j_len + 1) ; i++) { /* everything but commit_bh */ bn = reiserfs_get_journal_block(s) + (jl->j_start+i) % JOURNAL_BLOCK_COUNT; - tbh = get_hash_table(s->s_dev, bn, s->s_blocksize) ; + tbh = sb_get_hash_table(s, bn) ; /* kill this sanity check */ if (count > (orig_commit_left + 2)) { @@ -712,7 +712,7 @@ reiserfs_panic(s, "journal-539: flush_commit_list: BAD count(%d) > orig_commit_l for (i = 0 ; atomic_read(&(jl->j_commit_left)) > 1 && i < (jl->j_len + 1) ; i++) { /* everything but commit_bh */ bn = reiserfs_get_journal_block(s) + (jl->j_start + i) % JOURNAL_BLOCK_COUNT ; - tbh = get_hash_table(s->s_dev, bn, s->s_blocksize) ; + tbh = sb_get_hash_table(s, bn) ; wait_on_buffer(tbh) ; if (!buffer_uptodate(tbh)) { @@ -1403,8 +1403,7 @@ static int journal_transaction_is_valid(struct super_block *p_s_sb, struct buffe offset = d_bh->b_blocknr - reiserfs_get_journal_block(p_s_sb) ; /* ok, we have a journal description block, lets see if the transaction was valid */ - c_bh = bread(p_s_sb->s_dev, reiserfs_get_journal_block(p_s_sb) + ((offset + le32_to_cpu(desc->j_len) + 1) % JOURNAL_BLOCK_COUNT), - p_s_sb->s_blocksize) ; + c_bh = sb_bread(p_s_sb, reiserfs_get_journal_block(p_s_sb) + ((offset + le32_to_cpu(desc->j_len) + 1) % JOURNAL_BLOCK_COUNT)) ; if (!c_bh) return 0 ; commit = (struct reiserfs_journal_commit *)c_bh->b_data ; @@ -1458,7 +1457,7 @@ static int journal_read_transaction(struct super_block *p_s_sb, unsigned long cu unsigned long trans_offset ; int i; - d_bh = bread(p_s_sb->s_dev, cur_dblock, p_s_sb->s_blocksize) ; + d_bh = sb_bread(p_s_sb, cur_dblock) ; if (!d_bh) return 1 ; desc = (struct reiserfs_journal_desc *)d_bh->b_data ; @@ -1482,8 +1481,7 @@ static int journal_read_transaction(struct super_block *p_s_sb, unsigned long cu brelse(d_bh) ; return 1 ; } - c_bh = bread(p_s_sb->s_dev, reiserfs_get_journal_block(p_s_sb) + ((trans_offset + le32_to_cpu(desc->j_len) + 1) % JOURNAL_BLOCK_COUNT), - p_s_sb->s_blocksize) ; + c_bh = sb_bread(p_s_sb, reiserfs_get_journal_block(p_s_sb) + ((trans_offset + le32_to_cpu(desc->j_len) + 1) % JOURNAL_BLOCK_COUNT)) ; if (!c_bh) { brelse(d_bh) ; return 1 ; @@ -1512,11 +1510,11 @@ static int journal_read_transaction(struct super_block *p_s_sb, unsigned long cu } /* get all the buffer heads */ for(i = 0 ; i < le32_to_cpu(desc->j_len) ; i++) { - log_blocks[i] = getblk(p_s_sb->s_dev, reiserfs_get_journal_block(p_s_sb) + (trans_offset + 1 + i) % JOURNAL_BLOCK_COUNT, p_s_sb->s_blocksize); + log_blocks[i] = sb_getblk(p_s_sb, reiserfs_get_journal_block(p_s_sb) + (trans_offset + 1 + i) % JOURNAL_BLOCK_COUNT); if (i < JOURNAL_TRANS_HALF) { - real_blocks[i] = getblk(p_s_sb->s_dev, le32_to_cpu(desc->j_realblock[i]), p_s_sb->s_blocksize) ; + real_blocks[i] = sb_getblk(p_s_sb, le32_to_cpu(desc->j_realblock[i])) ; } else { - real_blocks[i] = getblk(p_s_sb->s_dev, le32_to_cpu(commit->j_realblock[i - JOURNAL_TRANS_HALF]), p_s_sb->s_blocksize) ; + real_blocks[i] = sb_getblk(p_s_sb, le32_to_cpu(commit->j_realblock[i - JOURNAL_TRANS_HALF])) ; } if (real_blocks[i]->b_blocknr >= reiserfs_get_journal_block(p_s_sb) && real_blocks[i]->b_blocknr < (reiserfs_get_journal_block(p_s_sb)+JOURNAL_BLOCK_COUNT)) { @@ -1617,10 +1615,9 @@ static int journal_read(struct super_block *p_s_sb) { ** is the first unflushed, and if that transaction is not valid, ** replay is done */ - SB_JOURNAL(p_s_sb)->j_header_bh = bread(p_s_sb->s_dev, + SB_JOURNAL(p_s_sb)->j_header_bh = sb_bread(p_s_sb, reiserfs_get_journal_block(p_s_sb) + - JOURNAL_BLOCK_COUNT, - p_s_sb->s_blocksize) ; + JOURNAL_BLOCK_COUNT) ; if (!SB_JOURNAL(p_s_sb)->j_header_bh) { return 1 ; } @@ -1641,7 +1638,7 @@ static int journal_read(struct super_block *p_s_sb) { ** there is nothing more we can do, and it makes no sense to read ** through the whole log. */ - d_bh = bread(p_s_sb->s_dev, reiserfs_get_journal_block(p_s_sb) + le32_to_cpu(jh->j_first_unflushed_offset), p_s_sb->s_blocksize) ; + d_bh = sb_bread(p_s_sb, reiserfs_get_journal_block(p_s_sb) + le32_to_cpu(jh->j_first_unflushed_offset)) ; ret = journal_transaction_is_valid(p_s_sb, d_bh, NULL, NULL) ; if (!ret) { continue_replay = 0 ; @@ -1661,7 +1658,7 @@ static int journal_read(struct super_block *p_s_sb) { ** all the valid transactions, and pick out the oldest. */ while(continue_replay && cur_dblock < (reiserfs_get_journal_block(p_s_sb) + JOURNAL_BLOCK_COUNT)) { - d_bh = bread(p_s_sb->s_dev, cur_dblock, p_s_sb->s_blocksize) ; + d_bh = sb_bread(p_s_sb, cur_dblock) ; ret = journal_transaction_is_valid(p_s_sb, d_bh, &oldest_invalid_trans_id, &newest_mount_id) ; if (ret == 1) { desc = (struct reiserfs_journal_desc *)d_bh->b_data ; @@ -2553,7 +2550,7 @@ int journal_mark_freed(struct reiserfs_transaction_handle *th, struct super_bloc int cleaned = 0 ; if (reiserfs_dont_log(th->t_super)) { - bh = get_hash_table(p_s_sb->s_dev, blocknr, p_s_sb->s_blocksize) ; + bh = sb_get_hash_table(p_s_sb, blocknr) ; if (bh && buffer_dirty (bh)) { printk ("journal_mark_freed(dont_log): dirty buffer on hash list: %lx %ld\n", bh->b_state, blocknr); BUG (); @@ -2561,7 +2558,7 @@ int journal_mark_freed(struct reiserfs_transaction_handle *th, struct super_bloc brelse (bh); return 0 ; } - bh = get_hash_table(p_s_sb->s_dev, blocknr, p_s_sb->s_blocksize) ; + bh = sb_get_hash_table(p_s_sb, blocknr) ; /* if it is journal new, we just remove it from this transaction */ if (bh && buffer_journal_new(bh)) { mark_buffer_notjournal_new(bh) ; @@ -2768,7 +2765,7 @@ static int do_journal_end(struct reiserfs_transaction_handle *th, struct super_b rs = SB_DISK_SUPER_BLOCK(p_s_sb) ; /* setup description block */ - d_bh = getblk(p_s_sb->s_dev, reiserfs_get_journal_block(p_s_sb) + SB_JOURNAL(p_s_sb)->j_start, p_s_sb->s_blocksize) ; + d_bh = sb_getblk(p_s_sb, reiserfs_get_journal_block(p_s_sb) + SB_JOURNAL(p_s_sb)->j_start) ; mark_buffer_uptodate(d_bh, 1) ; desc = (struct reiserfs_journal_desc *)(d_bh)->b_data ; memset(desc, 0, sizeof(struct reiserfs_journal_desc)) ; @@ -2776,9 +2773,8 @@ static int do_journal_end(struct reiserfs_transaction_handle *th, struct super_b desc->j_trans_id = cpu_to_le32(SB_JOURNAL(p_s_sb)->j_trans_id) ; /* setup commit block. Don't write (keep it clean too) this one until after everyone else is written */ - c_bh = getblk(p_s_sb->s_dev, reiserfs_get_journal_block(p_s_sb) + - ((SB_JOURNAL(p_s_sb)->j_start + SB_JOURNAL(p_s_sb)->j_len + 1) % JOURNAL_BLOCK_COUNT), - p_s_sb->s_blocksize) ; + c_bh = sb_getblk(p_s_sb, reiserfs_get_journal_block(p_s_sb) + + ((SB_JOURNAL(p_s_sb)->j_start + SB_JOURNAL(p_s_sb)->j_len + 1) % JOURNAL_BLOCK_COUNT)) ; commit = (struct reiserfs_journal_commit *)c_bh->b_data ; memset(commit, 0, sizeof(struct reiserfs_journal_commit)) ; commit->j_trans_id = cpu_to_le32(SB_JOURNAL(p_s_sb)->j_trans_id) ; @@ -2866,9 +2862,8 @@ printk("journal-2020: do_journal_end: BAD desc->j_len is ZERO\n") ; /* copy all the real blocks into log area. dirty log blocks */ if (test_bit(BH_JDirty, &cn->bh->b_state)) { struct buffer_head *tmp_bh ; - tmp_bh = getblk(p_s_sb->s_dev, reiserfs_get_journal_block(p_s_sb) + - ((cur_write_start + jindex) % JOURNAL_BLOCK_COUNT), - p_s_sb->s_blocksize) ; + tmp_bh = sb_getblk(p_s_sb, reiserfs_get_journal_block(p_s_sb) + + ((cur_write_start + jindex) % JOURNAL_BLOCK_COUNT)) ; mark_buffer_uptodate(tmp_bh, 1) ; memcpy(tmp_bh->b_data, cn->bh->b_data, cn->bh->b_size) ; jindex++ ; diff --git a/fs/reiserfs/lbalance.c b/fs/reiserfs/lbalance.c index 64f2dba60..9046956d5 100644 --- a/fs/reiserfs/lbalance.c +++ b/fs/reiserfs/lbalance.c @@ -63,7 +63,7 @@ static void leaf_copy_dir_entries (struct buffer_info * dest_bi, struct buffer_h /* form item header */ memcpy (&new_ih.ih_key, &ih->ih_key, KEY_SIZE); - put_ih_version( &new_ih, KEY_FORMAT_3_5 ); + put_ih_version( &new_ih, ITEM_VERSION_1 ); /* calculate item len */ put_ih_item_len( &new_ih, DEH_SIZE * copy_count + copy_records_len ); put_ih_entry_count( &new_ih, 0 ); @@ -78,7 +78,7 @@ static void leaf_copy_dir_entries (struct buffer_info * dest_bi, struct buffer_h set_le_ih_k_offset (&new_ih, U32_MAX); /* this item is not yet valid, but we want I_IS_DIRECTORY_ITEM to return 1 for it, so we -1 */ } - set_le_key_k_type (KEY_FORMAT_3_5, &(new_ih.ih_key), TYPE_DIRENTRY); + set_le_key_k_type (ITEM_VERSION_1, &(new_ih.ih_key), TYPE_DIRENTRY); } /* insert item into dest buffer */ diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index a81e7417b..de5ddcca9 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c @@ -17,6 +17,17 @@ #include <linux/reiserfs_fs.h> #include <linux/smp_lock.h> + /* there should be an overview right + here, as there should be in every + conceptual grouping of code. This + should be combined with dir.c and + called dir.c (naming will become + too large to be called one file in + a few years), stop senselessly + imitating the incoherent + structuring of code used by other + filesystems. */ + #define INC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) { i->i_nlink++; if (i->i_nlink >= REISERFS_LINK_MAX) i->i_nlink=1; } #define DEC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) i->i_nlink--; @@ -94,7 +105,7 @@ static inline void store_de_entry_key (struct reiserfs_dir_entry * de) BUG (); /* store key of the found entry */ - de->de_entry_key.version = KEY_FORMAT_3_5; + de->de_entry_key.version = ITEM_VERSION_1; de->de_entry_key.on_disk_key.k_dir_id = le32_to_cpu (de->de_ih->ih_key.k_dir_id); de->de_entry_key.on_disk_key.k_objectid = le32_to_cpu (de->de_ih->ih_key.k_objectid); set_cpu_key_k_offset (&(de->de_entry_key), deh_offset (deh)); @@ -336,7 +347,7 @@ static int reiserfs_find_entry (struct inode * dir, const char * name, int namel // at the ext2 code and comparing. It's subfunctions contain no code // used as a template unless they are so labeled. // -static struct dentry * reiserfs_lookup (struct inode * dir, struct dentry * dentry) +struct dentry * reiserfs_lookup (struct inode * dir, struct dentry * dentry) { int retval; struct inode * inode = 0; @@ -362,6 +373,7 @@ static struct dentry * reiserfs_lookup (struct inode * dir, struct dentry * dent return NULL; } + // // a portion of this function, particularly the VFS interface portion, // was derived from minix or ext2's analog and evolved as the @@ -506,7 +518,7 @@ static int reiserfs_add_entry (struct reiserfs_transaction_handle *th, struct in // at the ext2 code and comparing. It's subfunctions contain no code // used as a template unless they are so labeled. // -static int reiserfs_create (struct inode * dir, struct dentry *dentry, int mode) +int reiserfs_create (struct inode * dir, struct dentry *dentry, int mode) { int retval; struct inode * inode; @@ -562,7 +574,7 @@ static int reiserfs_create (struct inode * dir, struct dentry *dentry, int mode) // at the ext2 code and comparing. It's subfunctions contain no code // used as a template unless they are so labeled. // -static int reiserfs_mknod (struct inode * dir, struct dentry *dentry, int mode, int rdev) +int reiserfs_mknod (struct inode * dir, struct dentry *dentry, int mode, int rdev) { int retval; struct inode * inode; @@ -617,7 +629,7 @@ static int reiserfs_mknod (struct inode * dir, struct dentry *dentry, int mode, // at the ext2 code and comparing. It's subfunctions contain no code // used as a template unless they are so labeled. // -static int reiserfs_mkdir (struct inode * dir, struct dentry *dentry, int mode) +int reiserfs_mkdir (struct inode * dir, struct dentry *dentry, int mode) { int retval; struct inode * inode; @@ -696,20 +708,17 @@ static inline int reiserfs_empty_dir(struct inode *inode) { // at the ext2 code and comparing. It's subfunctions contain no code // used as a template unless they are so labeled. // -static int reiserfs_rmdir (struct inode * dir, struct dentry *dentry) +int reiserfs_rmdir (struct inode * dir, struct dentry *dentry) { int retval; struct inode * inode; int windex ; struct reiserfs_transaction_handle th ; - int jbegin_count; + int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3; INITIALIZE_PATH (path); struct reiserfs_dir_entry de; - /* we will be doing 2 balancings and update 2 stat data */ - jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 + 2; - journal_begin(&th, dir->i_sb, jbegin_count) ; windex = push_journal_writer("reiserfs_rmdir") ; @@ -753,9 +762,6 @@ static int reiserfs_rmdir (struct inode * dir, struct dentry *dentry) dir->i_blocks = ((dir->i_size + 511) >> 9); reiserfs_update_sd (&th, dir); - /* prevent empty directory from getting lost */ - add_save_link (&th, inode, 0/* not truncate */); - pop_journal_writer(windex) ; journal_end(&th, dir->i_sb, jbegin_count) ; reiserfs_check_path(&path) ; @@ -779,7 +785,7 @@ static int reiserfs_rmdir (struct inode * dir, struct dentry *dentry) // at the ext2 code and comparing. It's subfunctions contain no code // used as a template unless they are so labeled. // -static int reiserfs_unlink (struct inode * dir, struct dentry *dentry) +int reiserfs_unlink (struct inode * dir, struct dentry *dentry) { int retval; struct inode * inode; @@ -787,13 +793,7 @@ static int reiserfs_unlink (struct inode * dir, struct dentry *dentry) INITIALIZE_PATH (path); int windex ; struct reiserfs_transaction_handle th ; - int jbegin_count; - - inode = dentry->d_inode; - - /* in this transaction we can be doing at max two balancings and update - two stat datas */ - jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 + 2; + int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3; journal_begin(&th, dir->i_sb, jbegin_count) ; windex = push_journal_writer("reiserfs_unlink") ; @@ -803,6 +803,7 @@ static int reiserfs_unlink (struct inode * dir, struct dentry *dentry) retval = -ENOENT; goto end_unlink; } + inode = dentry->d_inode; reiserfs_update_inode_transaction(inode) ; reiserfs_update_inode_transaction(dir) ; @@ -833,10 +834,6 @@ static int reiserfs_unlink (struct inode * dir, struct dentry *dentry) dir->i_ctime = dir->i_mtime = CURRENT_TIME; reiserfs_update_sd (&th, dir); - if (!inode->i_nlink) - /* prevent file from getting lost */ - add_save_link (&th, inode, 0/* not truncate */); - pop_journal_writer(windex) ; journal_end(&th, dir->i_sb, jbegin_count) ; reiserfs_check_path(&path) ; @@ -858,7 +855,7 @@ static int reiserfs_unlink (struct inode * dir, struct dentry *dentry) // at the ext2 code and comparing. It's subfunctions contain no code // used as a template unless they are so labeled. // -static int reiserfs_symlink (struct inode * dir, struct dentry * dentry, const char * symname) +int reiserfs_symlink (struct inode * dir, struct dentry * dentry, const char * symname) { int retval; struct inode * inode; @@ -935,7 +932,7 @@ static int reiserfs_symlink (struct inode * dir, struct dentry * dentry, const c // at the ext2 code and comparing. It's subfunctions contain no code // used as a template unless they are so labeled. // -static int reiserfs_link (struct dentry * old_dentry, struct inode * dir, struct dentry * dentry) +int reiserfs_link (struct dentry * old_dentry, struct inode * dir, struct dentry * dentry) { int retval; struct inode *inode = old_dentry->d_inode; @@ -1035,8 +1032,8 @@ static void set_ino_in_dir_entry (struct reiserfs_dir_entry * de, struct key * k * one path. If it holds 2 or more, it can get into endless waiting in * get_empty_nodes or its clones */ -static int reiserfs_rename (struct inode * old_dir, struct dentry *old_dentry, - struct inode * new_dir, struct dentry *new_dentry) +int reiserfs_rename (struct inode * old_dir, struct dentry *old_dentry, + struct inode * new_dir, struct dentry *new_dentry) { int retval; INITIALIZE_PATH (old_entry_path); @@ -1047,13 +1044,8 @@ static int reiserfs_rename (struct inode * old_dir, struct dentry *old_dentry, struct inode * old_inode, * new_inode; int windex ; struct reiserfs_transaction_handle th ; - int jbegin_count ; - + int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3; - /* two balancings: old name removal, new name insertion or "save" link, - stat data updates: old directory and new directory and maybe block - containing ".." of renamed directory */ - jbegin_count = JOURNAL_PER_BALANCE_CNT * 3 + 3; old_inode = old_dentry->d_inode; new_inode = new_dentry->d_inode; @@ -1104,8 +1096,8 @@ static int reiserfs_rename (struct inode * old_dir, struct dentry *old_dentry, // FIXME: is it possible, that new_inode == 0 here? If yes, it // is not clear how does ext2 handle that if (!new_inode) { - reiserfs_panic (old_dir->i_sb, - "vs-7050: new entry is found, new inode == 0\n"); + printk ("reiserfs_rename: new entry is found, new inode == 0\n"); + BUG (); } } else if (retval) { pop_journal_writer(windex) ; @@ -1172,6 +1164,13 @@ static int reiserfs_rename (struct inode * old_dir, struct dentry *old_dentry, reiserfs_restore_prepared_buffer (old_inode->i_sb, new_de.de_bh); if (S_ISDIR(old_inode->i_mode)) reiserfs_restore_prepared_buffer (old_inode->i_sb, dot_dot_de.de_bh); +#if 0 + // FIXME: do we need this? shouldn't we simply continue? + run_task_queue(&tq_disk); + current->policy |= SCHED_YIELD; + /*current->counter = 0;*/ + schedule(); +#endif continue; } @@ -1196,25 +1195,29 @@ static int reiserfs_rename (struct inode * old_dir, struct dentry *old_dentry, if (new_inode) { // adjust link number of the victim if (S_ISDIR(new_inode->i_mode)) { - new_inode->i_nlink = 0; + DEC_DIR_INODE_NLINK(new_inode) } else { - new_inode->i_nlink--; + new_inode->i_nlink--; } new_inode->i_ctime = CURRENT_TIME; } if (S_ISDIR(old_inode->i_mode)) { - // adjust ".." of renamed directory + //if (dot_dot_de.de_bh) { + // adjust ".." of renamed directory set_ino_in_dir_entry (&dot_dot_de, INODE_PKEY (new_dir)); journal_mark_dirty (&th, new_dir->i_sb, dot_dot_de.de_bh); - - if (!new_inode) - /* there (in new_dir) was no directory, so it got new link - (".." of renamed directory) */ - INC_DIR_INODE_NLINK(new_dir); - - /* old directory lost one link - ".. " of renamed directory */ - DEC_DIR_INODE_NLINK(old_dir); + + DEC_DIR_INODE_NLINK(old_dir) + if (new_inode) { + if (S_ISDIR(new_inode->i_mode)) { + DEC_DIR_INODE_NLINK(new_inode) + } else { + new_inode->i_nlink--; + } + } else { + INC_DIR_INODE_NLINK(new_dir) + } } // looks like in 2.3.99pre3 brelse is atomic. so we can use pathrelse @@ -1225,40 +1228,18 @@ static int reiserfs_rename (struct inode * old_dir, struct dentry *old_dentry, // anybody, but it will panic if will not be able to find the // entry. This needs one more clean up if (reiserfs_cut_from_item (&th, &old_entry_path, &(old_de.de_entry_key), old_dir, NULL, 0) < 0) - reiserfs_warning ("vs-7060: reiserfs_rename: couldn't not cut old name. Fsck later?\n"); + reiserfs_warning ("vs-: reiserfs_rename: coudl not cut old name. Fsck later?\n"); old_dir->i_size -= DEH_SIZE + old_de.de_entrylen; old_dir->i_blocks = ((old_dir->i_size + 511) >> 9); reiserfs_update_sd (&th, old_dir); reiserfs_update_sd (&th, new_dir); - - if (new_inode) { - if (new_inode->i_nlink == 0) - add_save_link (&th, new_inode, 0/* not truncate */); + if (new_inode) reiserfs_update_sd (&th, new_inode); - } pop_journal_writer(windex) ; journal_end(&th, old_dir->i_sb, jbegin_count) ; return 0; } - - -/* - * directories can handle most operations... - */ -struct inode_operations reiserfs_dir_inode_operations = { - //&reiserfs_dir_operations, /* default_file_ops */ - create: reiserfs_create, - lookup: reiserfs_lookup, - link: reiserfs_link, - unlink: reiserfs_unlink, - symlink: reiserfs_symlink, - mkdir: reiserfs_mkdir, - rmdir: reiserfs_rmdir, - mknod: reiserfs_mknod, - rename: reiserfs_rename, -}; - diff --git a/fs/reiserfs/objectid.c b/fs/reiserfs/objectid.c index 7ce8d4a54..78e84e750 100644 --- a/fs/reiserfs/objectid.c +++ b/fs/reiserfs/objectid.c @@ -162,7 +162,7 @@ void reiserfs_release_objectid (struct reiserfs_transaction_handle *th, i += 2; } - reiserfs_warning ("vs-15011: reiserfs_release_objectid: tried to free free object id (%lu)\n", + reiserfs_warning ("vs-15010: reiserfs_release_objectid: tried to free free object id (%lu)", ( long unsigned ) objectid_to_release); } diff --git a/fs/reiserfs/prints.c b/fs/reiserfs/prints.c index 79706e940..5fce65fec 100644 --- a/fs/reiserfs/prints.c +++ b/fs/reiserfs/prints.c @@ -109,7 +109,7 @@ static void sprintf_de_head( char *buf, struct reiserfs_de_head *deh ) static void sprintf_item_head (char * buf, struct item_head * ih) { if (ih) { - sprintf (buf, "%s", (ih_version (ih) == KEY_FORMAT_3_6) ? "*3.6* " : "*3.5*"); + sprintf (buf, "%s", (ih_version (ih) == ITEM_VERSION_2) ? "*NEW* " : "*OLD*"); sprintf_le_key (buf + strlen (buf), &(ih->ih_key)); sprintf (buf + strlen (buf), ", item_len %d, item_location %d, " "free_space(entry_count) %d", diff --git a/fs/reiserfs/resize.c b/fs/reiserfs/resize.c index 2d038566c..ab7a31036 100644 --- a/fs/reiserfs/resize.c +++ b/fs/reiserfs/resize.c @@ -39,7 +39,7 @@ int reiserfs_resize (struct super_block * s, unsigned long block_count_new) } /* check the device size */ - bh = bread(s->s_dev, block_count_new - 1, s->s_blocksize); + bh = sb_bread(s, block_count_new - 1); if (!bh) { printk("reiserfs_resize: can\'t read last block\n"); return -EINVAL; @@ -111,7 +111,7 @@ int reiserfs_resize (struct super_block * s, unsigned long block_count_new) for (i = 0; i < bmap_nr; i++) bitmap[i] = SB_AP_BITMAP(s)[i]; for (i = bmap_nr; i < bmap_nr_new; i++) { - bitmap[i] = getblk(s->s_dev, i * s->s_blocksize * 8, s->s_blocksize); + bitmap[i] = reiserfs_getblk(s->s_dev, i * s->s_blocksize * 8, s->s_blocksize); memset(bitmap[i]->b_data, 0, sb->s_blocksize); reiserfs_test_and_set_le_bit(0, bitmap[i]->b_data); diff --git a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c index 21a75f4e9..327bd7311 100644 --- a/fs/reiserfs/stree.c +++ b/fs/reiserfs/stree.c @@ -225,7 +225,7 @@ inline void le_key2cpu_key (struct cpu_key * to, const struct key * from) // find out version of the key to->version = le_key_version (from); - if (to->version == KEY_FORMAT_3_5) { + if (to->version == ITEM_VERSION_1) { to->on_disk_key.u.k_offset_v1.k_offset = le32_to_cpu (from->u.k_offset_v1.k_offset); to->on_disk_key.u.k_offset_v1.k_uniqueness = le32_to_cpu (from->u.k_offset_v1.k_uniqueness); } else { @@ -604,7 +604,7 @@ static void search_by_key_reada (struct super_block * s, int blocknr) if (blocknr == 0) return; - bh = getblk (s->s_dev, blocknr, s->s_blocksize); + bh = reiserfs_getblk (s->s_dev, blocknr, s->s_blocksize); if (!buffer_uptodate (bh)) { ll_rw_block (READA, 1, &bh); @@ -727,11 +727,7 @@ int search_by_key (struct super_block * p_s_sb, continue; } - /* only check that the key is in the buffer if p_s_key is not - equal to the MAX_KEY. Latter case is only possible in - "finish_unfinished()" processing during mount. */ - RFALSE( COMP_KEYS( &MAX_KEY, p_s_key ) && - ! key_in_buffer(p_s_search_path, p_s_key, p_s_sb), + RFALSE( ! key_in_buffer(p_s_search_path, p_s_key, p_s_sb), "PAP-5130: key is not in the buffer"); #ifdef CONFIG_REISERFS_CHECK if ( cur_tb ) { @@ -921,7 +917,7 @@ static inline int prepare_for_direct_item (struct path * path, } // new file gets truncated - if (get_inode_item_key_version (inode) == KEY_FORMAT_3_6) { + if (inode_items_version (inode) == ITEM_VERSION_2) { // round_len = ROUND_UP (new_file_length); /* this was n_new_file_length < le_ih ... */ @@ -996,6 +992,10 @@ static char prepare_for_delete_or_cut( struct item_head * p_le_ih = PATH_PITEM_HEAD(p_s_path); struct buffer_head * p_s_bh = PATH_PLAST_BUFFER(p_s_path); +#ifdef CONFIG_REISERFS_CHECK + int n_repeat_counter = 0; +#endif + /* Stat_data item. */ if ( is_statdata_le_ih (p_le_ih) ) { @@ -1020,11 +1020,13 @@ static char prepare_for_delete_or_cut( { int n_unfm_number, /* Number of the item unformatted nodes. */ n_counter, + n_retry, /* Set to one if there is unformatted node buffer in use. */ n_blk_size; __u32 * p_n_unfm_pointer; /* Pointer to the unformatted node number. */ __u32 tmp; struct item_head s_ih; /* Item header. */ char c_mode; /* Returned mode of the balance. */ + struct buffer_head * p_s_un_bh; int need_research; @@ -1097,8 +1099,8 @@ static char prepare_for_delete_or_cut( // note: path could be changed, first line in for loop takes care // of it - for (n_counter = *p_n_removed; - n_counter < n_unfm_number; n_counter++, p_n_unfm_pointer-- ) { + for ( n_retry = 0, n_counter = *p_n_removed; + n_counter < n_unfm_number; n_counter++, p_n_unfm_pointer-- ) { if (item_moved (&s_ih, p_s_path)) { need_research = 1 ; @@ -1108,23 +1110,69 @@ static char prepare_for_delete_or_cut( p_n_unfm_pointer > (__u32 *)B_I_PITEM(p_s_bh, &s_ih) + I_UNFM_NUM(&s_ih) - 1, "vs-5265: pointer out of range"); - /* Hole, nothing to remove. */ - if ( ! get_block_num(p_n_unfm_pointer,0) ) { + if ( ! get_block_num(p_n_unfm_pointer,0) ) { /* Hole, nothing to remove. */ + if ( ! n_retry ) (*p_n_removed)++; - continue; + continue; + } + /* Search for the buffer in cache. */ + p_s_un_bh = sb_get_hash_table(p_s_sb, get_block_num(p_n_unfm_pointer,0)); + + if (p_s_un_bh) { + mark_buffer_clean(p_s_un_bh) ; + if (buffer_locked(p_s_un_bh)) { + __wait_on_buffer(p_s_un_bh) ; + } + /* even if the item moves, the block number of the + ** unformatted node we want to cut won't. So, it was + ** safe to clean the buffer here, this block _will_ + ** get freed during this call to prepare_for_delete_or_cut + */ + if ( item_moved (&s_ih, p_s_path) ) { + need_research = 1; + brelse(p_s_un_bh) ; + break ; + } } + if ( p_s_un_bh && block_in_use (p_s_un_bh)) { + /* Block is locked or held more than by one holder and by + journal. */ - (*p_n_removed)++; +#ifdef CONFIG_REISERFS_CHECK + if (n_repeat_counter && (n_repeat_counter % 100000) == 0) { + printk("prepare_for_delete, waiting on buffer %lu, b_count %d, %s%cJDIRTY %cJDIRTY_WAIT\n", + p_s_un_bh->b_blocknr, atomic_read (&p_s_un_bh->b_count), + buffer_locked (p_s_un_bh) ? "locked, " : "", + buffer_journaled(p_s_un_bh) ? ' ' : '!', + buffer_journal_dirty(p_s_un_bh) ? ' ' : '!') ; + + } +#endif + n_retry = 1; + brelse (p_s_un_bh); + continue; + } + + if ( ! n_retry ) + (*p_n_removed)++; + + RFALSE( p_s_un_bh && + get_block_num(p_n_unfm_pointer, 0) != p_s_un_bh->b_blocknr, + // note: minix_truncate allows that. As truncate is + // protected by down (inode->i_sem), two truncates can not + // co-exist + "PAP-5280: blocks numbers are different"); tmp = get_block_num(p_n_unfm_pointer,0); put_block_num(p_n_unfm_pointer, 0, 0); journal_mark_dirty (th, p_s_sb, p_s_bh); + bforget (p_s_un_bh); inode->i_blocks -= p_s_sb->s_blocksize / 512; reiserfs_free_block(th, tmp); if ( item_moved (&s_ih, p_s_path) ) { - need_research = 1; - break ; - } + need_research = 1; + break ; + } } /* a trick. If the buffer has been logged, this @@ -1134,6 +1182,28 @@ static char prepare_for_delete_or_cut( */ reiserfs_restore_prepared_buffer(p_s_sb, p_s_bh); + if ( n_retry ) { + /* There is block in use. Wait, they should release it soon */ + + RFALSE( *p_n_removed >= n_unfm_number, "PAP-5290: illegal case"); +#ifdef CONFIG_REISERFS_CHECK + if ( !(++n_repeat_counter % 500000) ) { + reiserfs_warning("PAP-5300: prepare_for_delete_or_cut: (pid %u): " + "could not delete item %k in (%d) iterations. New file length %Lu. (inode %Ld), Still trying\n", + current->pid, p_s_item_key, n_repeat_counter, n_new_file_length, inode->i_size); + if (n_repeat_counter == 5000000) { + print_block (PATH_PLAST_BUFFER(p_s_path), 3, + PATH_LAST_POSITION (p_s_path) - 2, PATH_LAST_POSITION (p_s_path) + 2); + reiserfs_panic(p_s_sb, "PAP-5305: prepare_for_delete_or_cut: key %k, new_file_length %Ld", + p_s_item_key, n_new_file_length); + } + } +#endif + + run_task_queue(&tq_disk); + current->policy |= SCHED_YIELD; + schedule(); + } /* This loop can be optimized. */ } while ( (*p_n_removed < n_unfm_number || need_research) && search_for_position_by_key(p_s_sb, p_s_item_key, p_s_path) == POSITION_FOUND ); @@ -1318,8 +1388,8 @@ int reiserfs_delete_item (struct reiserfs_transaction_handle *th, /* this deletes item which never gets split */ -void reiserfs_delete_solid_item (struct reiserfs_transaction_handle *th, - struct key * key) +static void reiserfs_delete_solid_item (struct reiserfs_transaction_handle *th, + struct key * key) { struct tree_balance tb; INITIALIZE_PATH (path); @@ -1333,13 +1403,13 @@ void reiserfs_delete_solid_item (struct reiserfs_transaction_handle *th, while (1) { retval = search_item (th->t_super, &cpu_key, &path); if (retval == IO_ERROR) { - reiserfs_warning ("vs-5350: reiserfs_delete_solid_item: " + reiserfs_warning ("vs-: reiserfs_delete_solid_item: " "i/o failure occurred trying to delete %K\n", &cpu_key); break; } if (retval != ITEM_FOUND) { pathrelse (&path); - reiserfs_warning ("vs-5355: reiserfs_delete_solid_item: %k not found", + reiserfs_warning ("vs-: reiserfs_delete_solid_item: %k not found", key); break; } @@ -1359,7 +1429,7 @@ void reiserfs_delete_solid_item (struct reiserfs_transaction_handle *th, } // IO_ERROR, NO_DISK_SPACE, etc - reiserfs_warning ("vs-5360: reiserfs_delete_solid_item: " + reiserfs_warning ("vs-: reiserfs_delete_solid_item: " "could not delete %K due to fix_nodes failure\n", &cpu_key); unfix_nodes (&tb); break; @@ -1376,6 +1446,15 @@ void reiserfs_delete_object (struct reiserfs_transaction_handle *th, struct inod /* for directory this deletes item containing "." and ".." */ reiserfs_do_truncate (th, inode, NULL, 0/*no timestamp updates*/); + /* delete stat data */ + /* this debug code needs to go away. Trying to find a truncate race + ** -- clm -- 4/1/2000 + */ +#if 0 + if (inode->i_nlink != 0) { + reiserfs_warning("clm-4001: deleting inode with link count==%d\n", inode->i_nlink) ; + } +#endif #if defined( USE_INODE_GENERATION_COUNTER ) if( !old_format_only ( th -> t_super ) ) { @@ -1412,7 +1491,7 @@ static int maybe_indirect_to_direct (struct reiserfs_transaction_handle *th, */ if (atomic_read(&p_s_inode->i_count) > 1 || !tail_has_to_be_packed (p_s_inode) || - !page || (p_s_inode->u.reiserfs_i.i_flags & i_nopack_mask)) { + !page || p_s_inode->u.reiserfs_i.nopack) { // leave tail in an unformatted node *p_c_mode = M_SKIP_BALANCING; cut_bytes = n_block_size - (n_new_file_size & (n_block_size - 1)); @@ -1614,7 +1693,7 @@ int reiserfs_cut_from_item (struct reiserfs_transaction_handle *th, ** be flushed before the transaction commits, so we don't need to ** deal with it here. */ - p_s_inode->u.reiserfs_i.i_flags &= ~i_pack_on_close_mask; + p_s_inode->u.reiserfs_i.i_pack_on_close = 0 ; } return n_ret_value; } @@ -1623,14 +1702,14 @@ int reiserfs_cut_from_item (struct reiserfs_transaction_handle *th, static void truncate_directory (struct reiserfs_transaction_handle *th, struct inode * inode) { if (inode->i_nlink) - reiserfs_warning ("vs-5655: truncate_directory: link count != 0\n"); + reiserfs_warning ("vs-5655: truncate_directory: link count != 0"); - set_le_key_k_offset (KEY_FORMAT_3_5, INODE_PKEY (inode), DOT_OFFSET); - set_le_key_k_type (KEY_FORMAT_3_5, INODE_PKEY (inode), TYPE_DIRENTRY); + set_le_key_k_offset (ITEM_VERSION_1, INODE_PKEY (inode), DOT_OFFSET); + set_le_key_k_type (ITEM_VERSION_1, INODE_PKEY (inode), TYPE_DIRENTRY); reiserfs_delete_solid_item (th, INODE_PKEY (inode)); - set_le_key_k_offset (KEY_FORMAT_3_5, INODE_PKEY (inode), SD_OFFSET); - set_le_key_k_type (KEY_FORMAT_3_5, INODE_PKEY (inode), TYPE_STAT_DATA); + set_le_key_k_offset (ITEM_VERSION_1, INODE_PKEY (inode), SD_OFFSET); + set_le_key_k_type (ITEM_VERSION_1, INODE_PKEY (inode), TYPE_STAT_DATA); } @@ -1703,7 +1782,6 @@ void reiserfs_do_truncate (struct reiserfs_transaction_handle *th, pathrelse(&s_search_path); return; } - /* Update key to search for the last file item. */ set_cpu_key_k_offset (&s_item_key, n_file_size); @@ -1740,6 +1818,7 @@ void reiserfs_do_truncate (struct reiserfs_transaction_handle *th, if (update_timestamps) { p_s_inode->i_mtime = p_s_inode->i_ctime = CURRENT_TIME; + // FIXME: sd gets wrong size here } reiserfs_update_sd(th, p_s_inode) ; diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 3da31d7d1..f36b63582 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -26,9 +26,6 @@ char reiserfs_super_magic_string[] = REISERFS_SUPER_MAGIC_STRING; char reiser2fs_super_magic_string[] = REISER2FS_SUPER_MAGIC_STRING; -static int reiserfs_remount (struct super_block * s, int * flags, char * data); -static int reiserfs_statfs (struct super_block * s, struct statfs * buf); - // // a portion of this function, particularly the VFS interface portion, // was derived from minix or ext2's analog and evolved as the @@ -36,7 +33,7 @@ static int reiserfs_statfs (struct super_block * s, struct statfs * buf); // at the ext2 code and comparing. It's subfunctions contain no code // used as a template unless they are so labeled. // -static void reiserfs_write_super (struct super_block * s) +void reiserfs_write_super (struct super_block * s) { int dirty = 0 ; @@ -55,7 +52,7 @@ static void reiserfs_write_super (struct super_block * s) // at the ext2 code and comparing. It's subfunctions contain no code // used as a template unless they are so labeled. // -static void reiserfs_write_super_lockfs (struct super_block * s) +void reiserfs_write_super_lockfs (struct super_block * s) { int dirty = 0 ; @@ -76,247 +73,6 @@ void reiserfs_unlockfs(struct super_block *s) { reiserfs_allow_writes(s) ; } -extern const struct key MAX_KEY; - - -/* this is used to delete "save link" when there are no items of a - file it points to. It can either happen if unlink is completed but - "save unlink" removal, or if file has both unlink and truncate - pending and as unlink completes first (because key of "save link" - protecting unlink is bigger that a key lf "save link" which - protects truncate), so there left no items to make truncate - completion on */ -static void remove_save_link_only (struct super_block * s, struct key * key) -{ - struct reiserfs_transaction_handle th; - - /* we are going to do one balancing */ - journal_begin (&th, s, JOURNAL_PER_BALANCE_CNT); - - reiserfs_delete_solid_item (&th, key); - if (is_direct_le_key (KEY_FORMAT_3_5, key)) - /* removals are protected by direct items */ - reiserfs_release_objectid (&th, le32_to_cpu (key->k_objectid)); - - journal_end (&th, s, JOURNAL_PER_BALANCE_CNT); -} - - -/* look for uncompleted unlinks and truncates and complete them */ -static void finish_unfinished (struct super_block * s) -{ - INITIALIZE_PATH (path); - struct cpu_key max_cpu_key, obj_key; - struct key save_link_key; - int retval; - struct item_head * ih; - struct buffer_head * bh; - int item_pos; - char * item; - int done; - struct inode * inode; - int truncate; - - - /* compose key to look for "save" links */ - max_cpu_key.version = KEY_FORMAT_3_5; - max_cpu_key.on_disk_key = MAX_KEY; - max_cpu_key.key_length = 3; - - done = 0; - s -> u.reiserfs_sb.s_is_unlinked_ok = 1; - while (1) { - retval = search_item (s, &max_cpu_key, &path); - if (retval != ITEM_NOT_FOUND) { - reiserfs_warning ("vs-2140: finish_unfinished: search_by_key returned %d\n", - retval); - break; - } - - bh = get_last_bh (&path); - item_pos = get_item_pos (&path); - if (item_pos != B_NR_ITEMS (bh)) { - reiserfs_warning ("vs-2060: finish_unfinished: wrong position found\n"); - break; - } - item_pos --; - ih = B_N_PITEM_HEAD (bh, item_pos); - - if (le32_to_cpu (ih->ih_key.k_dir_id) != MAX_KEY_OBJECTID) - /* there are no "save" links anymore */ - break; - - save_link_key = ih->ih_key; - if (is_indirect_le_ih (ih)) - truncate = 1; - else - truncate = 0; - - /* reiserfs_iget needs k_dirid and k_objectid only */ - item = B_I_PITEM (bh, ih); - obj_key.on_disk_key.k_dir_id = le32_to_cpu (*(__u32 *)item); - obj_key.on_disk_key.k_objectid = le32_to_cpu (ih->ih_key.k_objectid); - obj_key.on_disk_key.u.k_offset_v1.k_offset = 0; - obj_key.on_disk_key.u.k_offset_v1.k_uniqueness = 0; - - pathrelse (&path); - - inode = reiserfs_iget (s, &obj_key); - if (!inode) { - /* the unlink almost completed, it just did not manage to remove - "save" link and release objectid */ - reiserfs_warning ("vs-2180: finish_unfinished: iget failed for %K\n", - &obj_key); - remove_save_link_only (s, &save_link_key); - continue; - } - - if (!truncate && inode->i_nlink) { - /* file is not unlinked */ - reiserfs_warning ("vs-2185: finish_unfinished: file %K is not unlinked\n", - &obj_key); - remove_save_link_only (s, &save_link_key); - continue; - } - - if (truncate) { - inode -> u.reiserfs_i.i_flags |= i_link_saved_truncate_mask; - /* not completed truncate found. New size was committed together - with "save" link */ - reiserfs_warning ("Truncating %k to %Ld ..", - INODE_PKEY (inode), inode->i_size); - reiserfs_truncate_file (inode, 0/*don't update modification time*/); - remove_save_link (inode, truncate); - } else { - inode -> u.reiserfs_i.i_flags |= i_link_saved_unlink_mask; - /* not completed unlink (rmdir) found */ - reiserfs_warning ("Removing %k..", INODE_PKEY (inode)); - /* removal gets completed in iput */ - } - - iput (inode); - reiserfs_warning ("done\n"); - done ++; - } - s -> u.reiserfs_sb.s_is_unlinked_ok = 0; - - pathrelse (&path); - if (done) - reiserfs_warning ("There were %d uncompleted unlinks/truncates. " - "Completed\n", done); -} - -/* to protect file being unlinked from getting lost we "safe" link files - being unlinked. This link will be deleted in the same transaction with last - item of file. mounting the filesytem we scan all these links and remove - files which almost got lost */ -void add_save_link (struct reiserfs_transaction_handle * th, - struct inode * inode, int truncate) -{ - INITIALIZE_PATH (path); - int retval; - struct cpu_key key; - struct item_head ih; - __u32 link; - - /* file can only get one "save link" of each kind */ - RFALSE( truncate && - ( inode -> u.reiserfs_i.i_flags & i_link_saved_truncate_mask ), - "saved link already exists for truncated inode %lx", - ( long ) inode -> i_ino ); - RFALSE( !truncate && - ( inode -> u.reiserfs_i.i_flags & i_link_saved_unlink_mask ), - "saved link already exists for unlinked inode %lx", - ( long ) inode -> i_ino ); - - /* setup key of "save" link */ - key.version = KEY_FORMAT_3_5; - key.on_disk_key.k_dir_id = MAX_KEY_OBJECTID; - key.on_disk_key.k_objectid = inode->i_ino; - if (!truncate) { - /* unlink, rmdir, rename */ - set_cpu_key_k_offset (&key, 1 + inode->i_sb->s_blocksize); - set_cpu_key_k_type (&key, TYPE_DIRECT); - - /* item head of "safe" link */ - make_le_item_head (&ih, &key, key.version, 1 + inode->i_sb->s_blocksize, TYPE_DIRECT, - 4/*length*/, 0xffff/*free space*/); - } else { - /* truncate */ - set_cpu_key_k_offset (&key, 1); - set_cpu_key_k_type (&key, TYPE_INDIRECT); - - /* item head of "safe" link */ - make_le_item_head (&ih, &key, key.version, 1, TYPE_INDIRECT, - 4/*length*/, 0/*free space*/); - } - key.key_length = 3; - - /* look for its place in the tree */ - retval = search_item (inode->i_sb, &key, &path); - if (retval != ITEM_NOT_FOUND) { - reiserfs_warning ("vs-2100: add_save_link:" - "search_by_key (%K) returned %d\n", &key, retval); - pathrelse (&path); - return; - } - - /* body of "save" link */ - link = cpu_to_le32 (INODE_PKEY (inode)->k_dir_id); - - /* put "save" link inot tree */ - retval = reiserfs_insert_item (th, &path, &key, &ih, (char *)&link); - if (retval) - reiserfs_warning ("vs-2120: add_save_link: insert_item returned %d\n", - retval); - else { - if( truncate ) - inode -> u.reiserfs_i.i_flags |= i_link_saved_truncate_mask; - else - inode -> u.reiserfs_i.i_flags |= i_link_saved_unlink_mask; - } -} - - -/* this opens transaction unlike add_save_link */ -void remove_save_link (struct inode * inode, int truncate) -{ - struct reiserfs_transaction_handle th; - struct key key; - - - /* we are going to do one balancing only */ - journal_begin (&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT); - - /* setup key of "save" link */ - key.k_dir_id = cpu_to_le32 (MAX_KEY_OBJECTID); - key.k_objectid = INODE_PKEY (inode)->k_objectid; - if (!truncate) { - /* unlink, rmdir, rename */ - set_le_key_k_offset (KEY_FORMAT_3_5, &key, - 1 + inode->i_sb->s_blocksize); - set_le_key_k_type (KEY_FORMAT_3_5, &key, TYPE_DIRECT); - } else { - /* truncate */ - set_le_key_k_offset (KEY_FORMAT_3_5, &key, 1); - set_le_key_k_type (KEY_FORMAT_3_5, &key, TYPE_INDIRECT); - } - - if( ( truncate && - ( inode -> u.reiserfs_i.i_flags & i_link_saved_truncate_mask ) ) || - ( !truncate && - ( inode -> u.reiserfs_i.i_flags & i_link_saved_unlink_mask ) ) ) - reiserfs_delete_solid_item (&th, &key); - if (!truncate) { - reiserfs_release_objectid (&th, inode->i_ino); - inode -> u.reiserfs_i.i_flags &= ~i_link_saved_unlink_mask; - } else - inode -> u.reiserfs_i.i_flags &= ~i_link_saved_truncate_mask; - - journal_end (&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT); -} - - // // a portion of this function, particularly the VFS interface portion, // was derived from minix or ext2's analog and evolved as the @@ -324,7 +80,7 @@ void remove_save_link (struct inode * inode, int truncate) // at the ext2 code and comparing. It's subfunctions contain no code // used as a template unless they are so labeled. // -static void reiserfs_put_super (struct super_block * s) +void reiserfs_put_super (struct super_block * s) { int i; struct reiserfs_transaction_handle th ; @@ -367,26 +123,6 @@ static void reiserfs_put_super (struct super_block * s) return; } -/* we don't mark inodes dirty, we just log them */ -static void reiserfs_dirty_inode (struct inode * inode) { - struct reiserfs_transaction_handle th ; - - if (inode->i_sb->s_flags & MS_RDONLY) { - reiserfs_warning("clm-6006: writing inode %lu on readonly FS\n", - inode->i_ino) ; - return ; - } - lock_kernel() ; - - /* this is really only used for atime updates, so they don't have - ** to be included in O_SYNC or fsync - */ - journal_begin(&th, inode->i_sb, 1) ; - reiserfs_update_sd (&th, inode); - journal_end(&th, inode->i_sb, 1) ; - unlock_kernel() ; -} - struct super_operations reiserfs_sops = { read_inode: reiserfs_read_inode, @@ -495,7 +231,7 @@ int reiserfs_is_super(struct super_block *s) { // at the ext2 code and comparing. It's subfunctions contain no code // used as a template unless they are so labeled. // -static int reiserfs_remount (struct super_block * s, int * flags, char * data) +int reiserfs_remount (struct super_block * s, int * flags, char * data) { struct reiserfs_super_block * rs; struct reiserfs_transaction_handle th ; @@ -548,10 +284,6 @@ static int reiserfs_remount (struct super_block * s, int * flags, char * data) /* this will force a full flush of all journal lists */ SB_JOURNAL(s)->j_must_wait = 1 ; journal_end(&th, s, 10) ; - - if (!( *flags & MS_RDONLY ) ) - finish_unfinished( s ); - return 0; } @@ -876,7 +608,7 @@ int function2code (hashf_t func) // at the ext2 code and comparing. It's subfunctions contain no code // used as a template unless they are so labeled. // -static struct super_block * reiserfs_read_super (struct super_block * s, void * data, int silent) +struct super_block * reiserfs_read_super (struct super_block * s, void * data, int silent) { int size; struct inode *root_inode; @@ -1012,10 +744,6 @@ static struct super_block * reiserfs_read_super (struct super_block * s, void * journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s)); journal_end(&th, s, 1) ; - - /* look for files which were to be removed in previous session */ - finish_unfinished (s); - s->s_dirt = 0; } else { struct reiserfs_super_block * rs = SB_DISK_SUPER_BLOCK (s); @@ -1064,7 +792,7 @@ static struct super_block * reiserfs_read_super (struct super_block * s, void * // at the ext2 code and comparing. It's subfunctions contain no code // used as a template unless they are so labeled. // -static int reiserfs_statfs (struct super_block * s, struct statfs * buf) +int reiserfs_statfs (struct super_block * s, struct statfs * buf) { struct reiserfs_super_block * rs = SB_DISK_SUPER_BLOCK (s); @@ -1108,7 +836,6 @@ static void __exit exit_reiserfs_fs(void) unregister_filesystem(&reiserfs_fs_type); } - module_init(init_reiserfs_fs) ; module_exit(exit_reiserfs_fs) ; diff --git a/fs/reiserfs/tail_conversion.c b/fs/reiserfs/tail_conversion.c index d3734ec8c..775f81cbc 100644 --- a/fs/reiserfs/tail_conversion.c +++ b/fs/reiserfs/tail_conversion.c @@ -240,7 +240,7 @@ int indirect2direct (struct reiserfs_transaction_handle *th, /* Set direct item header to insert. */ - make_le_item_head (&s_ih, 0, get_inode_item_key_version (p_s_inode), pos1 + 1, + make_le_item_head (&s_ih, 0, inode_items_version (p_s_inode), pos1 + 1, TYPE_DIRECT, round_tail_len, 0xffff/*ih_free_space*/); /* we want a pointer to the first byte of the tail in the page. diff --git a/fs/romfs/inode.c b/fs/romfs/inode.c index 477d2eb68..9c791cbce 100644 --- a/fs/romfs/inode.c +++ b/fs/romfs/inode.c @@ -108,7 +108,7 @@ romfs_read_super(struct super_block *s, void *data, int silent) s->u.generic_sbp = (void *) 0; s->s_maxbytes = 0xFFFFFFFF; - bh = bread(dev, 0, ROMBSIZE); + bh = sb_bread(s, 0); if (!bh) { /* XXX merge with other printk? */ printk ("romfs: unable to read superblock\n"); @@ -188,7 +188,7 @@ romfs_strnlen(struct inode *i, unsigned long offset, unsigned long count) if (count > maxsize || offset+count > maxsize) count = maxsize-offset; - bh = bread(i->i_dev, offset>>ROMBSBITS, ROMBSIZE); + bh = sb_bread(i->i_sb, offset>>ROMBSBITS); if (!bh) return -1; /* error */ @@ -203,7 +203,7 @@ romfs_strnlen(struct inode *i, unsigned long offset, unsigned long count) while (res < count) { offset += maxsize; - bh = bread(i->i_dev, offset>>ROMBSBITS, ROMBSIZE); + bh = sb_bread(i->i_sb, offset>>ROMBSBITS); if (!bh) return -1; maxsize = min_t(unsigned long, count - res, ROMBSIZE); @@ -226,7 +226,7 @@ romfs_copyfrom(struct inode *i, void *dest, unsigned long offset, unsigned long if (offset >= maxsize || count > maxsize || offset+count>maxsize) return -1; - bh = bread(i->i_dev, offset>>ROMBSBITS, ROMBSIZE); + bh = sb_bread(i->i_sb, offset>>ROMBSBITS); if (!bh) return -1; /* error */ @@ -241,7 +241,7 @@ romfs_copyfrom(struct inode *i, void *dest, unsigned long offset, unsigned long offset += maxsize; dest += maxsize; - bh = bread(i->i_dev, offset>>ROMBSBITS, ROMBSIZE); + bh = sb_bread(i->i_sb, offset>>ROMBSBITS); if (!bh) return -1; maxsize = min_t(unsigned long, count - res, ROMBSIZE); diff --git a/fs/sysv/balloc.c b/fs/sysv/balloc.c index 1d76bb941..2f3df11dd 100644 --- a/fs/sysv/balloc.c +++ b/fs/sysv/balloc.c @@ -73,7 +73,7 @@ void sysv_free_block(struct super_block * sb, u32 nr) */ if (count == sb->sv_flc_size || count == 0) { block += sb->sv_block_base; - bh = getblk(sb->s_dev, block, sb->s_blocksize); + bh = sb_getblk(sb, block); if (!bh) { printk("sysv_free_block: getblk() failed\n"); unlock_super(sb); @@ -125,7 +125,7 @@ u32 sysv_new_block(struct super_block * sb) unsigned count; block += sb->sv_block_base; - if (!(bh = bread(sb->s_dev, block, sb->s_blocksize))) { + if (!(bh = sb_bread(sb, block))) { printk("sysv_new_block: cannot read free-list block\n"); /* retry this same block next time */ *sb->sv_bcache_count = cpu_to_fs16(sb, 1); @@ -196,7 +196,7 @@ unsigned long sysv_count_free_blocks(struct super_block * sb) if (block < sb->sv_firstdatazone || block >= sb->sv_nzones) goto Einval; block += sb->sv_block_base; - bh = bread(sb->s_dev, block, sb->s_blocksize); + bh = sb_bread(sb, block); if (!bh) goto Eio; n = fs16_to_cpu(sb, *(u16*)bh->b_data); diff --git a/fs/sysv/ialloc.c b/fs/sysv/ialloc.c index a91224c57..474e67ec6 100644 --- a/fs/sysv/ialloc.c +++ b/fs/sysv/ialloc.c @@ -55,7 +55,7 @@ sysv_raw_inode(struct super_block *sb, unsigned ino, struct buffer_head **bh) struct sysv_inode *res; int block = sb->sv_firstinodezone + sb->sv_block_base; block += (ino-1) >> sb->sv_inodes_per_block_bits; - *bh = bread(sb->s_dev, block, sb->s_blocksize); + *bh = sb_bread(sb, block); if (!*bh) return NULL; res = (struct sysv_inode *) (*bh)->b_data; diff --git a/fs/sysv/itree.c b/fs/sysv/itree.c index 76ff8d83c..5d4ef2979 100644 --- a/fs/sysv/itree.c +++ b/fs/sysv/itree.c @@ -86,8 +86,7 @@ static Indirect *get_branch(struct inode *inode, Indirect chain[], int *err) { - kdev_t dev = inode->i_dev; - int size = inode->i_sb->s_blocksize; + struct super_block *sb = inode->i_sb; Indirect *p = chain; struct buffer_head *bh; @@ -96,8 +95,8 @@ static Indirect *get_branch(struct inode *inode, if (!p->key) goto no_block; while (--depth) { - int block = block_to_cpu(inode->i_sb, p->key); - bh = bread(dev, block, size); + int block = block_to_cpu(sb, p->key); + bh = sb_bread(sb, block); if (!bh) goto failure; if (!verify_chain(chain, p)) @@ -139,7 +138,7 @@ static int alloc_branch(struct inode *inode, * the pointer to new one, then send parent to disk. */ parent = block_to_cpu(inode->i_sb, branch[n-1].key); - bh = getblk(inode->i_dev, parent, blocksize); + bh = sb_getblk(inode->i_sb, parent); lock_buffer(bh); memset(bh->b_data, 0, blocksize); branch[n].bh = bh; @@ -336,7 +335,7 @@ static void free_branches(struct inode *inode, u32 *p, u32 *q, int depth) continue; *p = 0; block = block_to_cpu(sb, nr); - bh = bread(inode->i_dev, block, sb->s_blocksize); + bh = sb_bread(sb, block); if (!bh) continue; free_branches(inode, (u32*)bh->b_data, diff --git a/fs/sysv/super.c b/fs/sysv/super.c index 983f0be5b..2a38452d7 100644 --- a/fs/sysv/super.c +++ b/fs/sysv/super.c @@ -362,11 +362,12 @@ static struct super_block *sysv_read_super(struct super_block *sb, if (64 != sizeof (struct sysv_inode)) panic("sysv fs: bad i-node size"); set_blocksize(dev,BLOCK_SIZE); + sb->s_blocksize = BLOCK_SIZE; sb->sv_block_base = 0; for (i = 0; i < sizeof(flavours)/sizeof(flavours[0]) && !size; i++) { brelse(bh); - bh = bread(dev, flavours[i].block, BLOCK_SIZE); + bh = sb_bread(sb, flavours[i].block); if (!bh) continue; size = flavours[i].test(sb, bh); @@ -380,8 +381,9 @@ static struct super_block *sysv_read_super(struct super_block *sb, blocknr = bh->b_blocknr << 1; brelse(bh); set_blocksize(dev, 512); - bh1 = bread(dev, blocknr, 512); - bh = bread(dev, blocknr + 1, 512); + sb->s_blocksize = 512; + bh1 = sb_bread(sb, blocknr); + bh = sb_bread(sb, blocknr + 1); break; case 2: bh1 = bh; @@ -390,7 +392,8 @@ static struct super_block *sysv_read_super(struct super_block *sb, blocknr = bh->b_blocknr >> 1; brelse(bh); set_blocksize(dev, 2048); - bh1 = bh = bread(dev, blocknr, 2048); + sb->s_blocksize = 2048; + bh1 = bh = sb_bread(sb, blocknr); break; default: goto Ebadsize; @@ -441,8 +444,9 @@ static struct super_block *v7_read_super(struct super_block *sb,void *data, sb->sv_bytesex = BYTESEX_PDP; set_blocksize(dev, 512); + sb->s_blocksize = 512; - if ((bh = bread(dev, 1, 512)) == NULL) { + if ((bh = sb_bread(sb, 1)) == NULL) { if (!silent) printk("VFS: unable to read V7 FS superblock on " "device %s.\n", bdevname(dev)); @@ -458,7 +462,7 @@ static struct super_block *v7_read_super(struct super_block *sb,void *data, /* plausibility check on root inode: it is a directory, with a nonzero size that is a multiple of 16 */ - if ((bh2 = bread(dev, 2, 512)) == NULL) + if ((bh2 = sb_bread(sb, 2)) == NULL) goto failed; v7i = (struct sysv_inode *)(bh2->b_data + 64); if ((fs16_to_cpu(sb,v7i->i_mode) & ~0777) != S_IFDIR || diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c index 982a7f808..8dc09bf96 100644 --- a/fs/udf/balloc.c +++ b/fs/udf/balloc.c @@ -98,7 +98,7 @@ static int read_block_bitmap(struct super_block * sb, loc.logicalBlockNum = bitmap->s_extPosition; loc.partitionReferenceNum = UDF_SB_PARTITION(sb); - bh = udf_tread(sb, udf_get_lb_pblock(sb, loc, block), sb->s_blocksize); + bh = udf_tread(sb, udf_get_lb_pblock(sb, loc, block)); if (!bh) { retval = -EIO; @@ -463,7 +463,7 @@ static void udf_table_free_blocks(struct super_block * sb, elen = 0; obloc = nbloc = UDF_I_LOCATION(table); - obh = nbh = udf_tread(sb, udf_get_lb_pblock(sb, nbloc, 0), sb->s_blocksize); + obh = nbh = udf_tread(sb, udf_get_lb_pblock(sb, nbloc, 0)); atomic_inc(&nbh->b_count); while (count && (etype = @@ -571,8 +571,7 @@ static void udf_table_free_blocks(struct super_block * sb, elen -= sb->s_blocksize; if (!(nbh = udf_tread(sb, - udf_get_lb_pblock(sb, nbloc, 0), - sb->s_blocksize))) + udf_get_lb_pblock(sb, nbloc, 0)))) { udf_release_data(obh); goto error_return; @@ -689,7 +688,7 @@ static int udf_table_prealloc_blocks(struct super_block * sb, extoffset = sizeof(struct UnallocatedSpaceEntry); bloc = UDF_I_LOCATION(table); - bh = udf_tread(sb, udf_get_lb_pblock(sb, bloc, 0), sb->s_blocksize); + bh = udf_tread(sb, udf_get_lb_pblock(sb, bloc, 0)); eloc.logicalBlockNum = 0xFFFFFFFF; while (first_block != eloc.logicalBlockNum && (etype = @@ -766,7 +765,7 @@ static int udf_table_new_block(struct super_block * sb, extoffset = sizeof(struct UnallocatedSpaceEntry); bloc = UDF_I_LOCATION(table); - goal_bh = bh = udf_tread(sb, udf_get_lb_pblock(sb, bloc, 0), sb->s_blocksize); + goal_bh = bh = udf_tread(sb, udf_get_lb_pblock(sb, bloc, 0)); atomic_inc(&goal_bh->b_count); while (spread && (etype = diff --git a/fs/udf/dir.c b/fs/udf/dir.c index 7a13d861c..f1dd42b3c 100644 --- a/fs/udf/dir.c +++ b/fs/udf/dir.c @@ -146,7 +146,7 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d return -ENOENT; } - if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block, dir->i_sb->s_blocksize))) + if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block))) { udf_release_data(bh); return -EIO; @@ -160,7 +160,7 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d for (num=0; i>0; i--) { block = udf_get_lb_pblock(dir->i_sb, eloc, offset+i); - tmp = udf_tgetblk(dir->i_sb, block, dir->i_sb->s_blocksize); + tmp = udf_tgetblk(dir->i_sb, block); if (tmp && !buffer_uptodate(tmp) && !buffer_locked(tmp)) bha[num++] = tmp; else diff --git a/fs/udf/directory.c b/fs/udf/directory.c index 33f5cf0b0..97ebc7e6d 100644 --- a/fs/udf/directory.c +++ b/fs/udf/directory.c @@ -60,7 +60,7 @@ Uint8 * udf_filead_read(struct inode *dir, Uint8 *tmpad, Uint8 ad_size, block = udf_get_lb_pblock(dir->i_sb, fe_loc, ++*pos); if (!block) return NULL; - if (!(*bh = udf_tread(dir->i_sb, block, dir->i_sb->s_blocksize))) + if (!(*bh = udf_tread(dir->i_sb, block))) return NULL; } else if (*offset > dir->i_sb->s_blocksize) @@ -74,7 +74,7 @@ Uint8 * udf_filead_read(struct inode *dir, Uint8 *tmpad, Uint8 ad_size, block = udf_get_lb_pblock(dir->i_sb, fe_loc, ++*pos); if (!block) return NULL; - if (!((*bh) = udf_tread(dir->i_sb, block, dir->i_sb->s_blocksize))) + if (!((*bh) = udf_tread(dir->i_sb, block))) return NULL; memcpy((Uint8 *)ad + remainder, (*bh)->b_data, ad_size - remainder); @@ -117,7 +117,7 @@ udf_fileident_read(struct inode *dir, loff_t *nf_pos, *extoffset = lextoffset; udf_release_data(fibh->sbh); - if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block, dir->i_sb->s_blocksize))) + if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block))) return NULL; fibh->soffset = fibh->eoffset = 0; @@ -129,7 +129,7 @@ udf_fileident_read(struct inode *dir, loff_t *nf_pos, for (num=0; i>0; i--) { block = udf_get_lb_pblock(dir->i_sb, *eloc, *offset+i); - tmp = udf_tgetblk(dir->i_sb, block, dir->i_sb->s_blocksize); + tmp = udf_tgetblk(dir->i_sb, block); if (tmp && !buffer_uptodate(tmp) && !buffer_locked(tmp)) bha[num++] = tmp; else @@ -183,7 +183,7 @@ udf_fileident_read(struct inode *dir, loff_t *nf_pos, fibh->soffset -= dir->i_sb->s_blocksize; fibh->eoffset -= dir->i_sb->s_blocksize; - if (!(fibh->ebh = udf_tread(dir->i_sb, block, dir->i_sb->s_blocksize))) + if (!(fibh->ebh = udf_tread(dir->i_sb, block))) return NULL; if (sizeof(struct FileIdentDesc) > - fibh->soffset) diff --git a/fs/udf/file.c b/fs/udf/file.c index 33ff39317..72ce82527 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c @@ -57,7 +57,7 @@ static int udf_adinicb_readpage(struct file *file, struct page * page) kaddr = kmap(page); memset(kaddr, 0, PAGE_CACHE_SIZE); block = udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0); - bh = bread (inode->i_dev, block, inode->i_sb->s_blocksize); + bh = sb_bread(inode->i_sb, block); memcpy(kaddr, bh->b_data + udf_ext0_offset(inode), inode->i_size); brelse(bh); flush_dcache_page(page); @@ -80,7 +80,7 @@ static int udf_adinicb_writepage(struct page *page) kaddr = kmap(page); block = udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0); - bh = bread (inode->i_dev, block, inode->i_sb->s_blocksize); + bh = sb_bread(inode->i_sb, block); memcpy(bh->b_data + udf_ext0_offset(inode), kaddr, inode->i_size); mark_buffer_dirty(bh); brelse(bh); @@ -105,7 +105,7 @@ static int udf_adinicb_commit_write(struct file *file, struct page *page, unsign char *kaddr = page_address(page); block = udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0); - bh = bread (inode->i_dev, block, inode->i_sb->s_blocksize); + bh = sb_bread(inode->i_sb, block); memcpy(bh->b_data + udf_file_entry_alloc_offset(inode) + offset, kaddr + offset, to-offset); mark_buffer_dirty(bh); @@ -246,8 +246,7 @@ int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, /* ok, we need to read the inode */ bh = udf_tread(inode->i_sb, - udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0), - inode->i_sb->s_blocksize); + udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0)); if (!bh) { diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 48431cec2..7b95bf925 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -184,7 +184,7 @@ void udf_expand_file_adinicb(struct inode * inode, int newsize, int * err) } block = udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0); - bh = udf_tread(inode->i_sb, block, inode->i_sb->s_blocksize); + bh = udf_tread(inode->i_sb, block); if (!bh) return; page = grab_cache_page(inode->i_mapping, 0); @@ -251,10 +251,10 @@ struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int UDF_I_LOCATION(inode).partitionReferenceNum, 0); if (!newblock) return NULL; - sbh = udf_tread(inode->i_sb, inode->i_ino, inode->i_sb->s_blocksize); + sbh = udf_tread(inode->i_sb, inode->i_ino); if (!sbh) return NULL; - dbh = udf_tgetblk(inode->i_sb, newblock, inode->i_sb->s_blocksize); + dbh = udf_tgetblk(inode->i_sb, newblock); if (!dbh) return NULL; lock_buffer(dbh); @@ -382,7 +382,7 @@ struct buffer_head * udf_getblk(struct inode * inode, long block, if (!*err && buffer_mapped(&dummy)) { struct buffer_head *bh; - bh = getblk(dummy.b_dev, dummy.b_blocknr, inode->i_sb->s_blocksize); + bh = sb_getblk(inode->i_sb, dummy.b_blocknr); if (buffer_new(&dummy)) { lock_buffer(bh); @@ -886,8 +886,7 @@ void udf_truncate(struct inode * inode) udf_file_entry_alloc_offset(inode); if ((bh = udf_tread(inode->i_sb, - udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0), - inode->i_sb->s_blocksize))) + udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0)))) { memset(bh->b_data + offset, 0x00, inode->i_sb->s_blocksize - offset); mark_buffer_dirty(bh); @@ -1322,8 +1321,7 @@ udf_update_inode(struct inode *inode, int do_sync) int err = 0; bh = udf_tread(inode->i_sb, - udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0), - inode->i_sb->s_blocksize); + udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0)); if (!bh) { @@ -1624,8 +1622,7 @@ Sint8 udf_add_aext(struct inode *inode, lb_addr *bloc, int *extoffset, if (!(*bh)) { if (!(*bh = udf_tread(inode->i_sb, - udf_get_lb_pblock(inode->i_sb, *bloc, 0), - inode->i_sb->s_blocksize))) + udf_get_lb_pblock(inode->i_sb, *bloc, 0)))) { udf_debug("reading block %d failed!\n", udf_get_lb_pblock(inode->i_sb, *bloc, 0)); @@ -1653,7 +1650,7 @@ Sint8 udf_add_aext(struct inode *inode, lb_addr *bloc, int *extoffset, return -1; } if (!(nbh = udf_tgetblk(inode->i_sb, udf_get_lb_pblock(inode->i_sb, - *bloc, 0), inode->i_sb->s_blocksize))) + *bloc, 0)))) { return -1; } @@ -1759,8 +1756,7 @@ Sint8 udf_write_aext(struct inode *inode, lb_addr bloc, int *extoffset, if (!(bh)) { if (!(bh = udf_tread(inode->i_sb, - udf_get_lb_pblock(inode->i_sb, bloc, 0), - inode->i_sb->s_blocksize))) + udf_get_lb_pblock(inode->i_sb, bloc, 0)))) { udf_debug("reading block %d failed!\n", udf_get_lb_pblock(inode->i_sb, bloc, 0)); @@ -1828,8 +1824,7 @@ Sint8 udf_next_aext(struct inode *inode, lb_addr *bloc, int *extoffset, if (!(*bh)) { if (!(*bh = udf_tread(inode->i_sb, - udf_get_lb_pblock(inode->i_sb, *bloc, 0), - inode->i_sb->s_blocksize))) + udf_get_lb_pblock(inode->i_sb, *bloc, 0)))) { udf_debug("reading block %d failed!\n", udf_get_lb_pblock(inode->i_sb, *bloc, 0)); @@ -1951,8 +1946,7 @@ Sint8 udf_current_aext(struct inode *inode, lb_addr *bloc, int *extoffset, if (!(*bh)) { if (!(*bh = udf_tread(inode->i_sb, - udf_get_lb_pblock(inode->i_sb, *bloc, 0), - inode->i_sb->s_blocksize))) + udf_get_lb_pblock(inode->i_sb, *bloc, 0)))) { udf_debug("reading block %d failed!\n", udf_get_lb_pblock(inode->i_sb, *bloc, 0)); @@ -2033,8 +2027,7 @@ Sint8 udf_insert_aext(struct inode *inode, lb_addr bloc, int extoffset, if (!bh) { if (!(bh = udf_tread(inode->i_sb, - udf_get_lb_pblock(inode->i_sb, bloc, 0), - inode->i_sb->s_blocksize))) + udf_get_lb_pblock(inode->i_sb, bloc, 0)))) { udf_debug("reading block %d failed!\n", udf_get_lb_pblock(inode->i_sb, bloc, 0)); @@ -2068,8 +2061,7 @@ Sint8 udf_delete_aext(struct inode *inode, lb_addr nbloc, int nextoffset, if (!(nbh)) { if (!(nbh = udf_tread(inode->i_sb, - udf_get_lb_pblock(inode->i_sb, nbloc, 0), - inode->i_sb->s_blocksize))) + udf_get_lb_pblock(inode->i_sb, nbloc, 0)))) { udf_debug("reading block %d failed!\n", udf_get_lb_pblock(inode->i_sb, nbloc, 0)); diff --git a/fs/udf/misc.c b/fs/udf/misc.c index 4b9cb0ef1..3cbebf75f 100644 --- a/fs/udf/misc.c +++ b/fs/udf/misc.c @@ -67,21 +67,21 @@ udf64_high32(Uint64 indat) #if defined(__linux__) && defined(__KERNEL__) extern struct buffer_head * -udf_tgetblk(struct super_block *sb, int block, int size) +udf_tgetblk(struct super_block *sb, int block) { if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV)) - return getblk(sb->s_dev, udf_fixed_to_variable(block), size); + return sb_getblk(sb, udf_fixed_to_variable(block)); else - return getblk(sb->s_dev, block, size); + return sb_getblk(sb, block); } extern struct buffer_head * -udf_tread(struct super_block *sb, int block, int size) +udf_tread(struct super_block *sb, int block) { if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV)) - return bread(sb->s_dev, udf_fixed_to_variable(block), size); + return sb_bread(sb, udf_fixed_to_variable(block)); else - return bread(sb->s_dev, block, size); + return sb_bread(sb, block); } extern struct GenericAttrFormat * @@ -92,7 +92,7 @@ udf_add_extendedattr(struct inode * inode, Uint32 size, Uint32 type, long_ad eaicb; int offset; - *bh = udf_tread(inode->i_sb, inode->i_ino, inode->i_sb->s_blocksize); + *bh = udf_tread(inode->i_sb, inode->i_ino); if (UDF_I_EXTENDED_FE(inode) == 0) { @@ -208,7 +208,7 @@ udf_get_extendedattr(struct inode * inode, Uint32 type, Uint8 subtype, long_ad eaicb; Uint32 offset; - *bh = udf_tread(inode->i_sb, inode->i_ino, inode->i_sb->s_blocksize); + *bh = udf_tread(inode->i_sb, inode->i_ino); if (UDF_I_EXTENDED_FE(inode) == 0) { @@ -273,7 +273,7 @@ udf_read_untagged(struct super_block *sb, Uint32 block, Uint32 offset) struct buffer_head *bh = NULL; /* Read the block */ - bh = udf_tread(sb, block+offset, sb->s_blocksize); + bh = udf_tread(sb, block+offset); if (!bh) { printk(KERN_ERR "udf: udf_read_untagged(%p,%d,%d) failed\n", @@ -305,7 +305,7 @@ udf_read_tagged(struct super_block *sb, Uint32 block, Uint32 location, Uint16 *i if (block == 0xFFFFFFFF) return NULL; - bh = udf_tread(sb, block, sb->s_blocksize); + bh = udf_tread(sb, block); if (!bh) { udf_debug("block=%d, location=%d: read failed\n", block, location); diff --git a/fs/udf/namei.c b/fs/udf/namei.c index 7b6f0a674..b36093c81 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c @@ -183,7 +183,7 @@ udf_find_entry(struct inode *dir, struct dentry *dentry, return NULL; } - if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block, dir->i_sb->s_blocksize))) + if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block))) { udf_release_data(bh); return NULL; @@ -404,7 +404,7 @@ udf_add_entry(struct inode *dir, struct dentry *dentry, else offset = 0; - if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block, dir->i_sb->s_blocksize))) + if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block))) { udf_release_data(bh); *err = -EIO; @@ -488,7 +488,7 @@ udf_add_entry(struct inode *dir, struct dentry *dentry, block = udf_get_lb_pblock(dir->i_sb, UDF_I_LOCATION(dir), 0); if (UDF_I_ALLOCTYPE(dir) == ICB_FLAG_AD_IN_ICB) { - fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block, dir->i_sb->s_blocksize); + fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block); fibh->soffset = fibh->eoffset = udf_file_entry_alloc_offset(dir); } else @@ -803,7 +803,7 @@ static int empty_dir(struct inode *dir) return 0; } - if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block, dir->i_sb->s_blocksize))) + if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block))) return 0; while ( (f_pos < size) ) @@ -964,7 +964,7 @@ static int udf_symlink(struct inode * dir, struct dentry * dentry, const char * block = udf_get_pblock(inode->i_sb, block, UDF_I_LOCATION(inode).partitionReferenceNum, 0); - bh = udf_tread(inode->i_sb, block, inode->i_sb->s_blocksize); + bh = udf_tread(inode->i_sb, block); lock_buffer(bh); memset(bh->b_data, 0x00, inode->i_sb->s_blocksize); mark_buffer_uptodate(bh, 1); @@ -974,7 +974,7 @@ static int udf_symlink(struct inode * dir, struct dentry * dentry, const char * else { block = udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0); - bh = udf_tread(inode->i_sb, block, inode->i_sb->s_blocksize); + bh = udf_tread(inode->i_sb, block); } ea = bh->b_data + udf_ext0_offset(inode); diff --git a/fs/udf/partition.c b/fs/udf/partition.c index 933f2db76..39382845c 100644 --- a/fs/udf/partition.c +++ b/fs/udf/partition.c @@ -76,7 +76,7 @@ Uint32 udf_get_pblock_virt15(struct super_block *sb, Uint32 block, Uint16 partit loc = udf_block_map(UDF_SB_VAT(sb), newblock); - if (!(bh = bread(sb->s_dev, loc, sb->s_blocksize))) + if (!(bh = sb_bread(sb, loc))) { udf_debug("get_pblock(UDF_VIRTUAL_MAP:%p,%d,%d) VAT: %d[%d]\n", sb, block, partition, loc, index); diff --git a/fs/udf/super.c b/fs/udf/super.c index 034064dfd..7afbe3af2 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -412,7 +412,7 @@ udf_vrs(struct super_block *sb, int silent) for (;!nsr02 && !nsr03; sector += sectorsize) { /* Read a block */ - bh = udf_tread(sb, sector >> sb->s_blocksize_bits, sb->s_blocksize); + bh = udf_tread(sb, sector >> sb->s_blocksize_bits); if (!bh) break; @@ -525,7 +525,7 @@ udf_find_anchor(struct super_block *sb) for (i=0; (!lastblock && i<sizeof(last)/sizeof(int)); i++) { - if (last[i] < 0 || !(bh = bread(sb->s_dev, last[i], sb->s_blocksize))) + if (last[i] < 0 || !(bh = sb_bread(sb, last[i]))) { ident = location = 0; } @@ -560,7 +560,7 @@ udf_find_anchor(struct super_block *sb) } else { - if (last[i] < 256 || !(bh = bread(sb->s_dev, last[i] - 256, sb->s_blocksize))) + if (last[i] < 256 || !(bh = sb_bread(sb, last[i] - 256))) { ident = location = 0; } @@ -579,8 +579,7 @@ udf_find_anchor(struct super_block *sb) } else { - if (last[i] < 312 + UDF_SB_SESSION(sb) || !(bh = bread(sb->s_dev, last[i] - 312 - UDF_SB_SESSION(sb), - sb->s_blocksize))) + if (last[i] < 312 + UDF_SB_SESSION(sb) || !(bh = sb_bread(sb, last[i] - 312 - UDF_SB_SESSION(sb)))) { ident = location = 0; } @@ -606,7 +605,7 @@ udf_find_anchor(struct super_block *sb) if (!lastblock) { /* We havn't found the lastblock. check 312 */ - if ((bh = bread(sb->s_dev, 312 + UDF_SB_SESSION(sb), sb->s_blocksize))) + if ((bh = sb_bread(sb, 312 + UDF_SB_SESSION(sb)))) { ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent); location = le32_to_cpu(((tag *)bh->b_data)->tagLocation); @@ -1258,7 +1257,7 @@ udf_load_partition(struct super_block *sb, lb_addr *fileset) Uint32 pos; pos = udf_block_map(UDF_SB_VAT(sb), 0); - bh = bread(sb->s_dev, pos, sb->s_blocksize); + bh = sb_bread(sb, pos); UDF_SB_TYPEVIRT(sb,i).s_start_offset = le16_to_cpu(((struct VirtualAllocationTable20 *)bh->b_data + udf_ext0_offset(UDF_SB_VAT(sb)))->lengthHeader) + udf_ext0_offset(UDF_SB_VAT(sb)); @@ -1728,7 +1727,7 @@ udf_count_free_bitmap(struct super_block *sb, struct udf_bitmap *bitmap) { udf_release_data(bh); newblock = udf_get_lb_pblock(sb, loc, ++block); - bh = udf_tread(sb, newblock, sb->s_blocksize); + bh = udf_tread(sb, newblock); if (!bh) { udf_debug("read failed\n"); diff --git a/fs/udf/symlink.c b/fs/udf/symlink.c index 543e9b45e..3254e530f 100644 --- a/fs/udf/symlink.c +++ b/fs/udf/symlink.c @@ -88,7 +88,7 @@ static int udf_symlink_filler(struct file *file, struct page *page) lock_kernel(); if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB) { - bh = udf_tread(inode->i_sb, inode->i_ino, inode->i_sb->s_blocksize); + bh = udf_tread(inode->i_sb, inode->i_ino); if (!bh) goto out; @@ -97,8 +97,7 @@ static int udf_symlink_filler(struct file *file, struct page *page) } else { - bh = bread(inode->i_dev, udf_block_map(inode, 0), - inode->i_sb->s_blocksize); + bh = sb_bread(inode->i_sb, udf_block_map(inode, 0)); if (!bh) goto out; diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h index 97dabb0ba..56d80d31c 100644 --- a/fs/udf/udfdecl.h +++ b/fs/udf/udfdecl.h @@ -139,8 +139,8 @@ extern void udf_discard_prealloc(struct inode *); /* misc.c */ extern int udf_read_tagged_data(char *, int size, int fd, int block, int partref); -extern struct buffer_head *udf_tgetblk(struct super_block *, int, int); -extern struct buffer_head *udf_tread(struct super_block *, int, int); +extern struct buffer_head *udf_tgetblk(struct super_block *, int); +extern struct buffer_head *udf_tread(struct super_block *, int); extern struct GenericAttrFormat *udf_add_extendedattr(struct inode *, Uint32, Uint32, Uint8, struct buffer_head **); extern struct GenericAttrFormat *udf_get_extendedattr(struct inode *, Uint32, Uint8, struct buffer_head **); extern struct buffer_head *udf_read_tagged(struct super_block *, Uint32, Uint32, Uint16 *); diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c index 38083eab4..31c1bdd0e 100644 --- a/fs/ufs/balloc.c +++ b/fs/ufs/balloc.c @@ -223,7 +223,7 @@ failed: #define NULLIFY_FRAGMENTS \ for (i = oldcount; i < newcount; i++) { \ - bh = getblk (sb->s_dev, result + i, sb->s_blocksize); \ + bh = sb_getblk(sb, result + i); \ memset (bh->b_data, 0, sb->s_blocksize); \ mark_buffer_uptodate(bh, 1); \ mark_buffer_dirty (bh); \ @@ -357,7 +357,7 @@ unsigned ufs_new_fragments (struct inode * inode, u32 * p, unsigned fragment, result = ufs_alloc_fragments (inode, cgno, goal, request, err); if (result) { for (i = 0; i < oldcount; i++) { - bh = bread (sb->s_dev, tmp + i, sb->s_blocksize); + bh = sb_bread(sb, tmp + i); if(bh) { mark_buffer_clean (bh); diff --git a/fs/ufs/cylinder.c b/fs/ufs/cylinder.c index 16aa99195..97391b4d6 100644 --- a/fs/ufs/cylinder.c +++ b/fs/ufs/cylinder.c @@ -54,7 +54,7 @@ static void ufs_read_cylinder (struct super_block * sb, */ UCPI_UBH->bh[0] = sb->u.ufs_sb.s_ucg[cgno]; for (i = 1; i < UCPI_UBH->count; i++) - if (!(UCPI_UBH->bh[i] = bread (sb->s_dev, UCPI_UBH->fragment + i, sb->s_blocksize))) + if (!(UCPI_UBH->bh[i] = sb_bread(sb, UCPI_UBH->fragment + i))) goto failed; sb->u.ufs_sb.s_cgno[bitmap_nr] = cgno; diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c index f333e5a2f..3dca14b36 100644 --- a/fs/ufs/dir.c +++ b/fs/ufs/dir.c @@ -74,7 +74,7 @@ ufs_readdir (struct file * filp, void * dirent, filldir_t filldir) while (!error && !stored && filp->f_pos < inode->i_size) { lblk = (filp->f_pos) >> sb->s_blocksize_bits; blk = ufs_frag_map(inode, lblk); - if (!blk || !(bh = bread (sb->s_dev, blk, sb->s_blocksize))) { + if (!blk || !(bh = sb_bread(sb, blk))) { /* XXX - error - skip to the next block */ printk("ufs_readdir: " "dir inode %lu has a hole at offset %lu\n", diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c index cff561ab9..5c3bc8f23 100644 --- a/fs/ufs/inode.c +++ b/fs/ufs/inode.c @@ -106,8 +106,7 @@ int ufs_frag_map(struct inode *inode, int frag) struct buffer_head *bh; int n = *p++; - bh = bread(sb->s_dev, uspi->s_sbbase + fs32_to_cpu(sb, block)+(n>>shift), - sb->s_blocksize); + bh = sb_bread(sb, uspi->s_sbbase + fs32_to_cpu(sb, block)+(n>>shift)); if (!bh) goto out; block = ((u32*) bh->b_data)[n & mask]; @@ -147,8 +146,7 @@ repeat: lastfrag = inode->u.ufs_i.i_lastfrag; if (tmp && fragment < lastfrag) { if (metadata) { - result = getblk (sb->s_dev, uspi->s_sbbase + tmp + blockoff, - sb->s_blocksize); + result = sb_getblk(sb, uspi->s_sbbase + tmp + blockoff); if (tmp == fs32_to_cpu(sb, *p)) { UFSD(("EXIT, result %u\n", tmp + blockoff)) return result; @@ -216,7 +214,7 @@ repeat: * now. -DaveM */ if (metadata) { - result = getblk (inode->i_dev, tmp + blockoff, sb->s_blocksize); + result = sb_getblk(inode->i_sb, tmp + blockoff); } else { *phys = tmp; result = NULL; @@ -264,8 +262,7 @@ repeat: tmp = fs32_to_cpu(sb, *p); if (tmp) { if (metadata) { - result = getblk (bh->b_dev, uspi->s_sbbase + tmp + blockoff, - sb->s_blocksize); + result = sb_getblk(sb, uspi->s_sbbase + tmp + blockoff); if (tmp == fs32_to_cpu(sb, *p)) goto out; brelse (result); @@ -292,7 +289,7 @@ repeat: * now. -DaveM */ if (metadata) { - result = getblk (bh->b_dev, tmp + blockoff, sb->s_blocksize); + result = sb_getblk(sb, tmp + blockoff); } else { *phys = tmp; *new = 1; @@ -425,7 +422,7 @@ struct buffer_head *ufs_getfrag(struct inode *inode, unsigned int fragment, *err = error; if (!error && buffer_mapped(&dummy)) { struct buffer_head *bh; - bh = getblk(dummy.b_dev, dummy.b_blocknr, inode->i_sb->s_blocksize); + bh = sb_getblk(inode->i_sb, dummy.b_blocknr); if (buffer_new(&dummy)) { memset(bh->b_data, 0, inode->i_sb->s_blocksize); mark_buffer_uptodate(bh, 1); @@ -500,7 +497,7 @@ void ufs_read_inode (struct inode * inode) return; } - bh = bread (sb->s_dev, uspi->s_sbbase + ufs_inotofsba(inode->i_ino), sb->s_blocksize); + bh = sb_bread(sb, uspi->s_sbbase + ufs_inotofsba(inode->i_ino)); if (!bh) { ufs_warning (sb, "ufs_read_inode", "unable to read inode %lu\n", inode->i_ino); return; @@ -591,7 +588,7 @@ static int ufs_update_inode(struct inode * inode, int do_sync) return -1; } - bh = bread (sb->s_dev, ufs_inotofsba(inode->i_ino), sb->s_blocksize); + bh = sb_bread(sb, ufs_inotofsba(inode->i_ino)); if (!bh) { ufs_warning (sb, "ufs_read_inode", "unable to read inode %lu\n", inode->i_ino); return -1; diff --git a/fs/ufs/super.c b/fs/ufs/super.c index 8cdb4c852..9421f5960 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c @@ -339,7 +339,7 @@ int ufs_read_cylinder_structures (struct super_block * sb) { size = uspi->s_bsize; if (i + uspi->s_fpb > blks) size = (blks - i) * uspi->s_fsize; - ubh = ubh_bread(sb->s_dev, uspi->s_csaddr + i, size); + ubh = ubh_bread(sb, uspi->s_csaddr + i, size); if (!ubh) goto failed; ubh_ubhcpymem (space, ubh, size); @@ -363,7 +363,7 @@ int ufs_read_cylinder_structures (struct super_block * sb) { } for (i = 0; i < uspi->s_ncg; i++) { UFSD(("read cg %u\n", i)) - if (!(sb->u.ufs_sb.s_ucg[i] = bread (sb->s_dev, ufs_cgcmin(i), sb->s_blocksize))) + if (!(sb->u.ufs_sb.s_ucg[i] = sb_bread(sb, ufs_cgcmin(i)))) goto failed; if (!ufs_cg_chkmagic (sb, (struct ufs_cylinder_group *) sb->u.ufs_sb.s_ucg[i]->b_data)) goto failed; @@ -414,7 +414,7 @@ void ufs_put_cylinder_structures (struct super_block * sb) { size = uspi->s_bsize; if (i + uspi->s_fpb > blks) size = (blks - i) * uspi->s_fsize; - ubh = ubh_bread (sb->s_dev, uspi->s_csaddr + i, size); + ubh = ubh_bread(sb, uspi->s_csaddr + i, size); ubh_memcpyubh (ubh, space, size); space += size; ubh_mark_buffer_uptodate (ubh, 1); @@ -597,11 +597,12 @@ struct super_block * ufs_read_super (struct super_block * sb, void * data, again: set_blocksize (sb->s_dev, block_size); + sb->s_blocksize = block_size; /* * read ufs super block from device */ - ubh = ubh_bread_uspi (uspi, sb->s_dev, uspi->s_sbbase + UFS_SBLOCK/block_size, super_block_size); + ubh = ubh_bread_uspi (uspi, sb, uspi->s_sbbase + UFS_SBLOCK/block_size, super_block_size); if (!ubh) goto failed; diff --git a/fs/ufs/truncate.c b/fs/ufs/truncate.c index e90fa8f7b..fc4cb9c38 100644 --- a/fs/ufs/truncate.c +++ b/fs/ufs/truncate.c @@ -114,7 +114,7 @@ static int ufs_trunc_direct (struct inode * inode) frag1 = ufs_fragnum (frag1); frag2 = ufs_fragnum (frag2); for (j = frag1; j < frag2; j++) { - bh = get_hash_table (sb->s_dev, tmp + j, uspi->s_fsize); + bh = sb_get_hash_table (sb, tmp + j); if ((bh && DATA_BUFFER_USED(bh)) || tmp != fs32_to_cpu(sb, *p)) { retry = 1; brelse (bh); @@ -137,7 +137,7 @@ next1: if (!tmp) continue; for (j = 0; j < uspi->s_fpb; j++) { - bh = get_hash_table (sb->s_dev, tmp + j, uspi->s_fsize); + bh = sb_get_hash_table(sb, tmp + j); if ((bh && DATA_BUFFER_USED(bh)) || tmp != fs32_to_cpu(sb, *p)) { retry = 1; brelse (bh); @@ -176,7 +176,7 @@ next2:; ufs_panic(sb, "ufs_truncate_direct", "internal error"); frag4 = ufs_fragnum (frag4); for (j = 0; j < frag4; j++) { - bh = get_hash_table (sb->s_dev, tmp + j, uspi->s_fsize); + bh = sb_get_hash_table (sb, tmp + j); if ((bh && DATA_BUFFER_USED(bh)) || tmp != fs32_to_cpu(sb, *p)) { retry = 1; brelse (bh); @@ -218,7 +218,7 @@ static int ufs_trunc_indirect (struct inode * inode, unsigned offset, u32 * p) tmp = fs32_to_cpu(sb, *p); if (!tmp) return 0; - ind_ubh = ubh_bread (sb->s_dev, tmp, uspi->s_bsize); + ind_ubh = ubh_bread(sb, tmp, uspi->s_bsize); if (tmp != fs32_to_cpu(sb, *p)) { ubh_brelse (ind_ubh); return 1; @@ -235,7 +235,7 @@ static int ufs_trunc_indirect (struct inode * inode, unsigned offset, u32 * p) if (!tmp) continue; for (j = 0; j < uspi->s_fpb; j++) { - bh = get_hash_table (sb->s_dev, tmp + j, uspi->s_fsize); + bh = sb_get_hash_table(sb, tmp + j); if ((bh && DATA_BUFFER_USED(bh)) || tmp != fs32_to_cpu(sb, *ind)) { retry = 1; brelse (bh); @@ -312,7 +312,7 @@ static int ufs_trunc_dindirect (struct inode * inode, unsigned offset, u32 * p) tmp = fs32_to_cpu(sb, *p); if (!tmp) return 0; - dind_bh = ubh_bread (inode->i_dev, tmp, uspi->s_bsize); + dind_bh = ubh_bread(sb, tmp, uspi->s_bsize); if (tmp != fs32_to_cpu(sb, *p)) { ubh_brelse (dind_bh); return 1; @@ -378,7 +378,7 @@ static int ufs_trunc_tindirect (struct inode * inode) p = inode->u.ufs_i.i_u1.i_data + UFS_TIND_BLOCK; if (!(tmp = fs32_to_cpu(sb, *p))) return 0; - tind_bh = ubh_bread (sb->s_dev, tmp, uspi->s_bsize); + tind_bh = ubh_bread (sb, tmp, uspi->s_bsize); if (tmp != fs32_to_cpu(sb, *p)) { ubh_brelse (tind_bh); return 1; diff --git a/fs/ufs/util.c b/fs/ufs/util.c index 06f2cb8d5..2d94ed553 100644 --- a/fs/ufs/util.c +++ b/fs/ufs/util.c @@ -23,7 +23,7 @@ struct ufs_buffer_head * _ubh_bread_ (struct ufs_sb_private_info * uspi, - kdev_t dev, unsigned fragment, unsigned size) + struct super_block *sb, unsigned fragment, unsigned size) { struct ufs_buffer_head * ubh; unsigned i, j, count; @@ -39,7 +39,7 @@ struct ufs_buffer_head * _ubh_bread_ (struct ufs_sb_private_info * uspi, ubh->fragment = fragment; ubh->count = count; for (i = 0; i < count; i++) - if (!(ubh->bh[i] = bread (dev, fragment + i, uspi->s_fsize))) + if (!(ubh->bh[i] = sb_bread(sb, fragment + i))) goto failed; for (; i < UFS_MAXFRAG; i++) ubh->bh[i] = NULL; @@ -51,7 +51,7 @@ failed: } struct ufs_buffer_head * ubh_bread_uspi (struct ufs_sb_private_info * uspi, - kdev_t dev, unsigned fragment, unsigned size) + struct super_block *sb, unsigned fragment, unsigned size) { unsigned i, j, count; if (size & ~uspi->s_fmask) @@ -62,7 +62,7 @@ struct ufs_buffer_head * ubh_bread_uspi (struct ufs_sb_private_info * uspi, USPI_UBH->fragment = fragment; USPI_UBH->count = count; for (i = 0; i < count; i++) - if (!(USPI_UBH->bh[i] = bread (dev, fragment + i, uspi->s_fsize))) + if (!(USPI_UBH->bh[i] = sb_bread(sb, fragment + i))) goto failed; for (; i < UFS_MAXFRAG; i++) USPI_UBH->bh[i] = NULL; diff --git a/fs/ufs/util.h b/fs/ufs/util.h index 5ee0ecb3c..2e5d47602 100644 --- a/fs/ufs/util.h +++ b/fs/ufs/util.h @@ -226,9 +226,9 @@ ufs_set_inode_gid(struct super_block *sb, struct ufs_inode *inode, u32 value) /* * These functions manipulate ufs buffers */ -#define ubh_bread(dev,fragment,size) _ubh_bread_(uspi,dev,fragment,size) -extern struct ufs_buffer_head * _ubh_bread_(struct ufs_sb_private_info *, kdev_t, unsigned, unsigned); -extern struct ufs_buffer_head * ubh_bread_uspi(struct ufs_sb_private_info *, kdev_t, unsigned, unsigned); +#define ubh_bread(sb,fragment,size) _ubh_bread_(uspi,sb,fragment,size) +extern struct ufs_buffer_head * _ubh_bread_(struct ufs_sb_private_info *, struct super_block *, unsigned, unsigned); +extern struct ufs_buffer_head * ubh_bread_uspi(struct ufs_sb_private_info *, struct super_block *, unsigned, unsigned); extern void ubh_brelse (struct ufs_buffer_head *); extern void ubh_brelse_uspi (struct ufs_sb_private_info *); extern void ubh_mark_buffer_dirty (struct ufs_buffer_head *); diff --git a/include/asm-m68k/machdep.h b/include/asm-m68k/machdep.h index 82badf63f..b7c3f7a28 100644 --- a/include/asm-m68k/machdep.h +++ b/include/asm-m68k/machdep.h @@ -38,7 +38,6 @@ extern unsigned long (*mach_hd_init) (unsigned long, unsigned long); extern void (*mach_hd_setup)(char *, int *); extern long mach_max_dma_address; extern void (*mach_floppy_setup)(char *, int *); -extern void (*mach_floppy_eject)(void); extern void (*mach_heartbeat) (int); extern void (*mach_l2_flush) (int); extern int mach_sysrq_key; diff --git a/include/linux/amigaffs.h b/include/linux/amigaffs.h index 3a264a7e9..39bbdbbe4 100644 --- a/include/linux/amigaffs.h +++ b/include/linux/amigaffs.h @@ -31,7 +31,7 @@ affs_bread(struct super_block *sb, int block) { pr_debug(KERN_DEBUG "affs_bread: %d\n", block); if (block >= AFFS_SB->s_reserved && block < AFFS_SB->s_partition_size) - return bread(sb->s_dev, block, sb->s_blocksize); + return sb_bread(sb, block); return NULL; } static inline struct buffer_head * @@ -39,7 +39,7 @@ affs_getblk(struct super_block *sb, int block) { pr_debug(KERN_DEBUG "affs_getblk: %d\n", block); if (block >= AFFS_SB->s_reserved && block < AFFS_SB->s_partition_size) - return getblk(sb->s_dev, block, sb->s_blocksize); + return sb_getblk(sb, block); return NULL; } static inline struct buffer_head * @@ -48,10 +48,11 @@ affs_getzeroblk(struct super_block *sb, int block) struct buffer_head *bh; pr_debug(KERN_DEBUG "affs_getzeroblk: %d\n", block); if (block >= AFFS_SB->s_reserved && block < AFFS_SB->s_partition_size) { - bh = getblk(sb->s_dev, block, sb->s_blocksize); - wait_on_buffer(bh); + bh = sb_getblk(sb, block); + lock_buffer(bh); memset(bh->b_data, 0 , sb->s_blocksize); mark_buffer_uptodate(bh, 1); + unlock_buffer(bh); return bh; } return NULL; @@ -62,7 +63,7 @@ affs_getemptyblk(struct super_block *sb, int block) struct buffer_head *bh; pr_debug(KERN_DEBUG "affs_getemptyblk: %d\n", block); if (block >= AFFS_SB->s_reserved && block < AFFS_SB->s_partition_size) { - bh = getblk(sb->s_dev, block, sb->s_blocksize); + bh = sb_getblk(sb, block); wait_on_buffer(bh); mark_buffer_uptodate(bh, 1); return bh; diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index a32ec05bb..620b149ec 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -157,6 +157,7 @@ struct request_queue * queue needs bounce pages for pages above this limit */ unsigned long bounce_pfn; + int bounce_gfp; /* * This is used to remove the plug when tq_disk runs. @@ -214,19 +215,22 @@ extern unsigned long blk_max_low_pfn, blk_max_pfn; #define BLK_BOUNCE_HIGH (blk_max_low_pfn << PAGE_SHIFT) #define BLK_BOUNCE_ANY (blk_max_pfn << PAGE_SHIFT) +#define BLK_BOUNCE_ISA (ISA_DMA_THRESHOLD) #ifdef CONFIG_HIGHMEM -extern void create_bounce(unsigned long pfn, struct bio **bio_orig); +extern void create_bounce(unsigned long pfn, int gfp, struct bio **bio_orig); +extern void init_emergency_isa_pool(void); extern inline void blk_queue_bounce(request_queue_t *q, struct bio **bio) { - create_bounce(q->bounce_pfn, bio); + create_bounce(q->bounce_pfn, q->bounce_gfp, bio); } #else /* CONFIG_HIGHMEM */ #define blk_queue_bounce(q, bio) do { } while (0) +#define init_emergency_isa_pool() do { } while (0) #endif /* CONFIG_HIGHMEM */ diff --git a/include/linux/fd.h b/include/linux/fd.h index c0ed2792b..187785b83 100644 --- a/include/linux/fd.h +++ b/include/linux/fd.h @@ -369,10 +369,4 @@ struct floppy_raw_cmd { #define FDEJECT _IO(2, 0x5a) /* eject the disk */ - -#ifdef __KERNEL__ -/* eject the boot floppy (if we need the drive for a different root floppy) */ -void floppy_eject(void); -#endif - #endif diff --git a/include/linux/fs.h b/include/linux/fs.h index 7f52b46d6..b1e59c161 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -21,7 +21,6 @@ #include <linux/cache.h> #include <linux/stddef.h> #include <linux/string.h> -#include <linux/bio.h> #include <asm/atomic.h> #include <asm/bitops.h> @@ -1363,6 +1362,7 @@ extern struct buffer_head * get_hash_table(kdev_t, sector_t, int); extern struct buffer_head * getblk(kdev_t, sector_t, int); extern void ll_rw_block(int, int, struct buffer_head * bh[]); extern int submit_bh(int, struct buffer_head *); +struct bio; extern int submit_bio(int, struct bio *); extern int is_read_only(kdev_t); extern void __brelse(struct buffer_head *); @@ -1379,6 +1379,18 @@ static inline void bforget(struct buffer_head *buf) } extern int set_blocksize(kdev_t, int); extern struct buffer_head * bread(kdev_t, int, int); +static inline struct buffer_head * sb_bread(struct super_block *sb, int block) +{ + return bread(sb->s_dev, block, sb->s_blocksize); +} +static inline struct buffer_head * sb_getblk(struct super_block *sb, int block) +{ + return getblk(sb->s_dev, block, sb->s_blocksize); +} +static inline struct buffer_head * sb_get_hash_table(struct super_block *sb, int block) +{ + return get_hash_table(sb->s_dev, block, sb->s_blocksize); +} extern void wakeup_bdflush(void); extern void put_unused_buffer_head(struct buffer_head * bh); extern struct buffer_head * get_unused_buffer_head(int async); diff --git a/include/linux/highmem.h b/include/linux/highmem.h index bc89d618b..8f375350f 100644 --- a/include/linux/highmem.h +++ b/include/linux/highmem.h @@ -2,6 +2,7 @@ #define _LINUX_HIGHMEM_H #include <linux/config.h> +#include <linux/bio.h> #include <asm/pgalloc.h> #ifdef CONFIG_HIGHMEM @@ -13,7 +14,7 @@ extern struct page *highmem_start_page; /* declarations for linux/mm/highmem.c */ unsigned int nr_free_highpages(void); -extern void create_bounce(unsigned long pfn, struct bio **bio_orig); +extern void create_bounce(unsigned long pfn, int gfp, struct bio **bio_orig); static inline char *bh_kmap(struct buffer_head *bh) { diff --git a/include/linux/iso_fs.h b/include/linux/iso_fs.h index 82dde8081..9cdfbaea4 100644 --- a/include/linux/iso_fs.h +++ b/include/linux/iso_fs.h @@ -219,7 +219,7 @@ int get_joliet_filename(struct iso_directory_record *, unsigned char *, struct i int get_acorn_filename(struct iso_directory_record *, char *, struct inode *); extern struct dentry *isofs_lookup(struct inode *, struct dentry *); -extern struct buffer_head *isofs_bread(struct inode *, unsigned int, unsigned int); +extern struct buffer_head *isofs_bread(struct inode *, unsigned int); extern int isofs_get_blocks(struct inode *, sector_t, struct buffer_head **, unsigned long); extern struct inode_operations isofs_dir_inode_operations; @@ -230,11 +230,11 @@ extern struct address_space_operations isofs_symlink_aops; #ifdef LEAK_CHECK #define free_s leak_check_free_s #define malloc leak_check_malloc -#define bread leak_check_bread +#define sb_bread leak_check_bread #define brelse leak_check_brelse extern void * leak_check_malloc(unsigned int size); extern void leak_check_free_s(void * obj, int size); -extern struct buffer_head * leak_check_bread(int dev, int block, int size); +extern struct buffer_head * leak_check_bread(struct super_block *sb, int block); extern void leak_check_brelse(struct buffer_head * bh); #endif /* LEAK_CHECK */ diff --git a/include/linux/qnx4_fs.h b/include/linux/qnx4_fs.h index dd9b7cb6e..55ba2f99d 100644 --- a/include/linux/qnx4_fs.h +++ b/include/linux/qnx4_fs.h @@ -118,7 +118,7 @@ extern int qnx4_unlink(struct inode *dir, struct dentry *dentry); extern int qnx4_rmdir(struct inode *dir, struct dentry *dentry); extern int qnx4_sync_file(struct file *file, struct dentry *dentry, int); extern int qnx4_sync_inode(struct inode *inode); -extern int qnx4_get_block(struct inode *inode, long iblock, struct buffer_head *bh, int create); +extern int qnx4_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh, int create); #endif /* __KERNEL__ */ diff --git a/include/linux/reiserfs_fs_i.h b/include/linux/reiserfs_fs_i.h index 6520bcab8..08445c120 100644 --- a/include/linux/reiserfs_fs_i.h +++ b/include/linux/reiserfs_fs_i.h @@ -3,47 +3,50 @@ #include <linux/list.h> -/** bitmasks for i_flags field in reiserfs-specific part of inode */ -typedef enum { - /** this says what format of key do all items (but stat data) of - an object have. If this is set, that format is 3.6 otherwise - - 3.5 */ - i_item_key_version_mask = 0x0001, - /** If this is unset, object has 3.5 stat data, otherwise, it has - 3.6 stat data with 64bit size, 32bit nlink etc. */ - i_stat_data_version_mask = 0x0002, - /** file might need tail packing on close */ - i_pack_on_close_mask = 0x0004, - /** don't pack tail of file */ - i_nopack_mask = 0x0008, - /** If those is set, "safe link" was created for this file during - truncate or unlink. Safe link is used to avoid leakage of disk - space on crash with some files open, but unlinked. */ - i_link_saved_unlink_mask = 0x0010, - i_link_saved_truncate_mask = 0x0020 -} reiserfs_inode_flags; - - struct reiserfs_inode_info { - __u32 i_key [4];/* key is still 4 32 bit integers */ + __u32 i_key [4];/* key is still 4 32 bit integers */ - /** transient inode flags that are never stored on disk. Bitmasks - for this field are defined above. */ - __u32 i_flags; - - __u32 i_first_direct_byte; // offset of first byte stored in direct item. - - int i_prealloc_block; /* first unused block of a sequence of unused blocks */ - int i_prealloc_count; /* length of that sequence */ - struct list_head i_prealloc_list; /* per-transaction list of inodes which - * have preallocated blocks */ + /* this comment will be totally + cryptic to readers not familiar + with 3.5/3.6 format conversion, and + it does not consider that that 3.6 + might not be the last version */ + int i_version; // this says whether file is old or new + + int i_pack_on_close ; // file might need tail packing on close + + __u32 i_first_direct_byte; // offset of first byte stored in direct item. + + /* My guess is this contains the first + unused block of a sequence of + blocks plus the length of the + sequence, which I think is always + at least two at the time of the + preallocation. I really prefer + allocate on flush conceptually..... + + You know, it really annoys me when + code is this badly commented that I + have to guess what it does. + Neither I nor anyone else has time + for guessing what your + datastructures mean. -Hans */ + //For preallocation + int i_prealloc_block; + int i_prealloc_count; + struct list_head i_prealloc_list; /* per-transaction list of inodes which + * have preallocated blocks */ + /* I regret that you think the below + is a comment you should make.... -Hans */ + //nopack-attribute + int nopack; - /* we use these for fsync or O_SYNC to decide which transaction - ** needs to be committed in order for this inode to be properly - ** flushed */ - unsigned long i_trans_id ; - unsigned long i_trans_index ; + /* we use these for fsync or O_SYNC to decide which transaction needs + ** to be committed in order for this inode to be properly flushed + */ + unsigned long i_trans_id ; + unsigned long i_trans_index ; }; -#endif +#endif diff --git a/include/linux/reiserfs_fs_sb.h b/include/linux/reiserfs_fs_sb.h index 32109db40..1eee601a1 100644 --- a/include/linux/reiserfs_fs_sb.h +++ b/include/linux/reiserfs_fs_sb.h @@ -420,10 +420,6 @@ struct reiserfs_sb_info int s_bmaps_without_search; int s_direct2indirect; int s_indirect2direct; - /* set up when it's ok for reiserfs_read_inode2() to read from - disk inode with nlink==0. Currently this is only used during - finish_unfinished() processing at mount time */ - int s_is_unlinked_ok; reiserfs_proc_info_data_t s_proc_info_data; struct proc_dir_entry *procdir; }; diff --git a/init/do_mounts.c b/init/do_mounts.c index e6a94292c..3aab59aec 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -351,23 +351,20 @@ static int __init create_dev(char *name, kdev_t dev, char *devfs_name) return sys_symlink(path + n + 5, name); } -#ifdef CONFIG_MAC_FLOPPY -int swim3_fd_eject(int devnum); -#endif static void __init change_floppy(char *fmt, ...) { extern void wait_for_keypress(void); char buf[80]; + int fd; va_list args; va_start(args, fmt); vsprintf(buf, fmt, args); va_end(args); -#ifdef CONFIG_BLK_DEV_FD - floppy_eject(); -#endif -#ifdef CONFIG_MAC_FLOPPY - swim3_fd_eject(MINOR(ROOT_DEV)); -#endif + fd = open("/dev/root", O_RDWR, 0); + if (fd >= 0) { + sys_ioctl(fd, FDEJECT, 0); + close(fd); + } printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf); wait_for_keypress(); } diff --git a/kernel/signal.c b/kernel/signal.c index 44acecd85..b6958912e 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -649,8 +649,10 @@ kill_proc_info(int sig, struct siginfo *info, pid_t pid) /* * kill_something_info() interprets pid in interesting ways just like kill(2). * - * POSIX specifies that kill(-1,sig) is unspecified, but what we have - * is probably wrong. Should make it like BSD or SYSV. + * POSIX (2001) specifies "If pid is -1, sig shall be sent to all processes + * (excluding an unspecified set of system processes) for which the process + * has permission to send that signal." + * So, probably the process should also signal itself. */ static int kill_something_info(int sig, struct siginfo *info, int pid) @@ -663,7 +665,7 @@ static int kill_something_info(int sig, struct siginfo *info, int pid) read_lock(&tasklist_lock); for_each_task(p) { - if (p->pid > 1 && p != current) { + if (p->pid > 1) { int err = send_sig_info(sig, info, p); ++count; if (err != -EPERM) diff --git a/mm/filemap.c b/mm/filemap.c index 58bbd4403..b9e9ff56e 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -2853,7 +2853,7 @@ generic_file_write(struct file *file,const char *buf,size_t count, loff_t *ppos) unsigned long limit = current->rlim[RLIMIT_FSIZE].rlim_cur; loff_t pos; struct page *page, *cached_page; - unsigned long written; + ssize_t written; long status = 0; int err; unsigned bytes; diff --git a/mm/highmem.c b/mm/highmem.c index 9b24d0a96..a727fe4d0 100644 --- a/mm/highmem.c +++ b/mm/highmem.c @@ -184,13 +184,14 @@ void kunmap_high(struct page *page) wake_up(&pkmap_map_wait); } -#define POOL_SIZE 64 +#define POOL_SIZE 64 +#define ISA_POOL_SIZE 16 -static mempool_t *page_pool; +static mempool_t *page_pool, *isa_page_pool; -static void * page_pool_alloc(int gfp_mask, void *data) +static void *page_pool_alloc(int gfp_mask, void *data) { - return alloc_page(gfp_mask & ~ __GFP_HIGHIO); + return alloc_page(gfp_mask); } static void page_pool_free(void *page, void *data) @@ -215,6 +216,23 @@ static __init int init_emergency_pool(void) return 0; } +/* + * gets called "every" time someone init's a queue with BLK_BOUNCE_ISA + * as the max address, so check if the pool has already been created. + */ +int init_emergency_isa_pool(void) +{ + if (isa_page_pool) + return 0; + + isa_page_pool = mempool_create(ISA_POOL_SIZE, page_pool_alloc, page_pool_free, NULL); + if (!isa_page_pool) + BUG(); + + printk("isa bounce pool size: %d pages\n", ISA_POOL_SIZE); + return 0; +} + __initcall(init_emergency_pool); /* @@ -248,7 +266,7 @@ static inline void copy_to_high_bio_irq(struct bio *to, struct bio *from) } } -static inline int bounce_end_io (struct bio *bio, int nr_sectors) +static inline int bounce_end_io (struct bio *bio, int nr_sectors, mempool_t *pool) { struct bio *bio_orig = bio->bi_private; struct bio_vec *bvec, *org_vec; @@ -267,7 +285,7 @@ static inline int bounce_end_io (struct bio *bio, int nr_sectors) if (bvec->bv_page == org_vec->bv_page) continue; - mempool_free(bvec->bv_page, page_pool); + mempool_free(bvec->bv_page, pool); } out_eio: @@ -279,28 +297,53 @@ out_eio: static int bounce_end_io_write(struct bio *bio, int nr_sectors) { - return bounce_end_io(bio, nr_sectors); + return bounce_end_io(bio, nr_sectors, page_pool); +} + +static int bounce_end_io_write_isa(struct bio *bio, int nr_sectors) +{ + return bounce_end_io(bio, nr_sectors, isa_page_pool); } -static int bounce_end_io_read (struct bio *bio, int nr_sectors) +static inline int __bounce_end_io_read(struct bio *bio, int nr_sectors, + mempool_t *pool) { struct bio *bio_orig = bio->bi_private; if (test_bit(BIO_UPTODATE, &bio->bi_flags)) copy_to_high_bio_irq(bio_orig, bio); - return bounce_end_io(bio, nr_sectors); + return bounce_end_io(bio, nr_sectors, pool); +} + +static int bounce_end_io_read(struct bio *bio, int nr_sectors) +{ + return __bounce_end_io_read(bio, nr_sectors, page_pool); } -void create_bounce(unsigned long pfn, struct bio **bio_orig) +static int bounce_end_io_read_isa(struct bio *bio, int nr_sectors) +{ + return __bounce_end_io_read(bio, nr_sectors, isa_page_pool); +} + +void create_bounce(unsigned long pfn, int gfp, struct bio **bio_orig) { struct page *page; struct bio *bio = NULL; - int i, rw = bio_data_dir(*bio_orig); + int i, rw = bio_data_dir(*bio_orig), bio_gfp; struct bio_vec *to, *from; + mempool_t *pool; BUG_ON((*bio_orig)->bi_idx); + if (!(gfp & GFP_DMA)) { + bio_gfp = GFP_NOHIGHIO; + pool = page_pool; + } else { + bio_gfp = GFP_NOIO; + pool = isa_page_pool; + } + bio_for_each_segment(from, *bio_orig, i) { page = from->bv_page; @@ -314,11 +357,11 @@ void create_bounce(unsigned long pfn, struct bio **bio_orig) * irk, bounce it */ if (!bio) - bio = bio_alloc(GFP_NOHIGHIO, (*bio_orig)->bi_vcnt); + bio = bio_alloc(bio_gfp, (*bio_orig)->bi_vcnt); to = &bio->bi_io_vec[i]; - to->bv_page = mempool_alloc(page_pool, GFP_NOHIGHIO); + to->bv_page = mempool_alloc(pool, gfp); to->bv_len = from->bv_len; to->bv_offset = from->bv_offset; @@ -359,10 +402,17 @@ void create_bounce(unsigned long pfn, struct bio **bio_orig) bio->bi_idx = 0; bio->bi_size = (*bio_orig)->bi_size; - if (rw & WRITE) - bio->bi_end_io = bounce_end_io_write; - else - bio->bi_end_io = bounce_end_io_read; + if (pool == page_pool) { + if (rw & WRITE) + bio->bi_end_io = bounce_end_io_write; + else + bio->bi_end_io = bounce_end_io_read; + } else { + if (rw & WRITE) + bio->bi_end_io = bounce_end_io_write_isa; + else + bio->bi_end_io = bounce_end_io_read_isa; + } bio->bi_private = *bio_orig; *bio_orig = bio; diff --git a/mm/mempool.c b/mm/mempool.c index 0c0bf9996..ecf1acc80 100644 --- a/mm/mempool.c +++ b/mm/mempool.c @@ -176,7 +176,8 @@ void mempool_destroy(mempool_t *pool) * * this function only sleeps if the alloc_fn function sleeps or * returns NULL. Note that due to preallocation, this function - * *never* fails. + * *never* fails when called from process contexts. (it might + * fail if called from an IRQ context.) */ void * mempool_alloc(mempool_t *pool, int gfp_mask) { @@ -185,7 +186,7 @@ void * mempool_alloc(mempool_t *pool, int gfp_mask) struct list_head *tmp; int curr_nr; DECLARE_WAITQUEUE(wait, current); - int gfp_nowait = gfp_mask & ~__GFP_WAIT; + int gfp_nowait = gfp_mask & ~(__GFP_WAIT | __GFP_IO); repeat_alloc: element = pool->alloc(gfp_nowait, pool->pool_data); @@ -196,15 +197,11 @@ repeat_alloc: * If the pool is less than 50% full then try harder * to allocate an element: */ - if (gfp_mask != gfp_nowait) { - if (pool->curr_nr <= pool->min_nr/2) { - element = pool->alloc(gfp_mask, pool->pool_data); - if (likely(element != NULL)) - return element; - } - } else - /* we must not sleep */ - return NULL; + if ((gfp_mask != gfp_nowait) && (pool->curr_nr <= pool->min_nr/2)) { + element = pool->alloc(gfp_mask, pool->pool_data); + if (likely(element != NULL)) + return element; + } /* * Kick the VM at this point. @@ -218,19 +215,25 @@ repeat_alloc: element = tmp; pool->curr_nr--; spin_unlock_irqrestore(&pool->lock, flags); - return element; } + spin_unlock_irqrestore(&pool->lock, flags); + + /* We must not sleep in the GFP_ATOMIC case */ + if (gfp_mask == gfp_nowait) + return NULL; + + run_task_queue(&tq_disk); + add_wait_queue_exclusive(&pool->wait, &wait); set_task_state(current, TASK_UNINTERRUPTIBLE); + spin_lock_irqsave(&pool->lock, flags); curr_nr = pool->curr_nr; spin_unlock_irqrestore(&pool->lock, flags); - if (!curr_nr) { - run_task_queue(&tq_disk); + if (!curr_nr) schedule(); - } current->state = TASK_RUNNING; remove_wait_queue(&pool->wait, &wait); |