From: NeilBrown Date: Sun, 20 Mar 2011 22:40:07 +0000 (+1100) Subject: Update to 2.6.38 X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=687ea563a925733d2a8e063b324f220674a2df7a;p=LaFS.git Update to 2.6.38 - evict inode replaces delete_inode/clear_inode and don't need drop_inode - setattr changes for truncate sequence - changes to sync_file - new shrinker signature - REQ_UNPLUG replaces BIO_RW_UNPLUG - open_bdev_exclusive replaced by blkdev_get_by_path and various bug fixes. Signed-off-by: NeilBrown --- diff --git a/Makefile b/Makefile index 6b40ab7..7751535 100644 --- a/Makefile +++ b/Makefile @@ -18,6 +18,7 @@ else KERNELDIR := /home/src/lafs-2.6.27 KERNELDIR := /home/src/lafs-2.6.34/OBJ +KERNELDIR := /home/src/lafs-2.6.38/OBJ all:: $(MAKE) -C $(KERNELDIR) ARCH=i386 M=`pwd` nm lafs.o | grep ' T ' | grep -v lafs_ diff --git a/dir.c b/dir.c index 0dd5045..c4a024a 100644 --- a/dir.c +++ b/dir.c @@ -1802,7 +1802,7 @@ lafs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) /* FIXME range check inum */ if (err < 0) - ERR_PTR(err); + return ERR_PTR(err); ino = lafs_iget(LAFSI(dir)->filesys, inum, SYNC); if (IS_ERR(ino)) diff --git a/file.c b/file.c index ee07bd9..0e73e70 100644 --- a/file.c +++ b/file.c @@ -430,16 +430,16 @@ static void lafs_sync_page(struct page *page) } static int -lafs_sync_file(struct file *file, struct dentry *de, int datasync) +lafs_sync_file(struct file *file, int datasync) { - int err; - err = lafs_sync_inode(de->d_inode, 0); + struct inode *ino = file->f_dentry->d_inode; + int err = lafs_sync_inode(ino, 0); /* FIXME I ignore datasync, just like file_fsync */ - err = write_inode_now(de->d_inode, 0) ?: err; + err = write_inode_now(ino, 0) ?: err; if (err == 0) - lafs_sync_inode(de->d_inode, 1); + lafs_sync_inode(ino, 1); return err; } diff --git a/index.c b/index.c index ed4fe20..bb2a01a 100644 --- a/index.c +++ b/index.c @@ -47,7 +47,8 @@ spinlock_t lafs_hash_lock; /* static */ struct freelists freelist; -static int lafs_shrinker(int nr_to_scan, /*gfp_t*/unsigned int gfp_mask) +static int lafs_shrinker(struct shrinker *s, + int nr_to_scan, /*gfp_t*/unsigned int gfp_mask) { if (nr_to_scan) { LIST_HEAD(togo); diff --git a/inode.c b/inode.c index 04b2188..cdaf128 100644 --- a/inode.c +++ b/inode.c @@ -842,73 +842,74 @@ void lafs_inode_init(struct datablock *b, int type, int mode, struct inode *dir) lafs_dirty_dblock(b); } -void lafs_clear_inode(struct inode *ino) -{ - struct lafs_inode *li = LAFSI(ino); - dprintk("CLEAR INODE %d\n", (int)ino->i_ino); - - li->type = 0; - - /* Now is a good time to break the linkage between - * inode and dblock - but not if the file is - * being deleted - */ - if (!test_bit(I_Deleting, &LAFSI(ino)->iflags)) { - struct datablock *db; - spin_lock(&ino->i_data.private_lock); - db = LAFSI(ino)->dblock; - if (db) { - struct indexblock *ib = LAFSI(ino)->iblock; - LAFS_BUG(ib && atomic_read(&ib->b.refcnt), &db->b); - db->my_inode = NULL; - LAFSI(ino)->dblock = NULL; - LAFSI(ino)->iblock = NULL; - } - spin_unlock(&ino->i_data.private_lock); - } - - /* FIXME release quota inodes if filesystem */ -} - static int inode_map_free(struct fs *fs, struct inode *fsys, u32 inum); -void lafs_delete_inode(struct inode *ino) +void lafs_evict_inode(struct inode *ino) { struct fs *fs = fs_from_inode(ino); - struct datablock *b; + struct lafs_inode *li = LAFSI(ino); if (ino->i_mode == 0) { /* There never was an inode here, * so nothing to do. + * We just call end_writeback to get the + * flags set properly. */ - clear_inode(ino); + end_writeback(ino); return; } - dprintk("DELETE INODE %d\n", (int)ino->i_ino); + + dprintk("EVICT INODE %d\n", (int)ino->i_ino); + /* Normal truncation holds an igrab, so we cannot be * deleted until any truncation finishes */ BUG_ON(test_bit(I_Trunc, &LAFSI(ino)->iflags)); - b = lafs_inode_dblock(ino, SYNC, MKREF(delete_inode)); + if (ino->i_nlink == 0) { + struct datablock *b = + lafs_inode_dblock(ino, SYNC, MKREF(delete_inode)); + i_size_write(ino, 0); + truncate_inode_pages(&ino->i_data, 0); + LAFSI(ino)->trunc_next = 0; + set_bit(I_Deleting, &LAFSI(ino)->iflags); + set_bit(I_Trunc, &LAFSI(ino)->iflags); + lafs_igrab_fs(ino); + if (!IS_ERR(b)) { + set_bit(B_Claimed, &b->b.flags); + lafs_add_orphan(fs, b); + dprintk("PUNCH hole for %d\n", (int)b->b.fileaddr); + putdref(b, MKREF(delete_inode)); + } + inode_map_free(fs, LAFSI(ino)->filesys, ino->i_ino); + } else + truncate_inode_pages(&ino->i_data, 0); + end_writeback(ino); - i_size_write(ino, 0); - truncate_inode_pages(&ino->i_data, 0); - LAFSI(ino)->trunc_next = 0; - set_bit(I_Deleting, &LAFSI(ino)->iflags); - set_bit(I_Trunc, &LAFSI(ino)->iflags); - lafs_igrab_fs(ino); + dprintk("CLEAR INODE %d\n", (int)ino->i_ino); - if (!IS_ERR(b)) { - set_bit(B_Claimed, &b->b.flags); - lafs_add_orphan(fs, b); - dprintk("PUNCH hole for %d\n", (int)b->b.fileaddr); - putdref(b, MKREF(delete_inode)); + li->type = 0; + + /* Now is a good time to break the linkage between + * inode and dblock - but not if the file is + * being deleted + */ + if (!test_bit(I_Deleting, &li->iflags)) { + struct datablock *db; + spin_lock(&ino->i_data.private_lock); + db = li->dblock; + if (db) { + struct indexblock *ib = li->iblock; + LAFS_BUG(ib && atomic_read(&ib->b.refcnt), &db->b); + db->my_inode = NULL; + li->dblock = NULL; + li->iblock = NULL; + } + spin_unlock(&ino->i_data.private_lock); } - inode_map_free(fs, LAFSI(ino)->filesys, ino->i_ino); - clear_inode(ino); + /* FIXME release quota inodes if filesystem */ } static int prune(void *data, u32 addr, u64 paddr, int len) @@ -1987,12 +1988,16 @@ again: lafs_checkpoint_unlock_wait(fs); goto again; } - /* inode_setattr calls lafs_dirty_inode, which sets - * I_Dirty so the dblock will get updated. - */ - err = err ?: inode_setattr(ino, attr); - if (!err) + + if (!err) { + if ((attr->ia_valid & ATTR_SIZE) && + attr->ia_size != i_size_read(ino)) + truncate_setsize(ino, attr->ia_size); + setattr_copy(ino, attr); + mark_inode_dirty(ino); + lafs_dirty_dblock(db); + } clear_bit(B_PinPending, &db->b.flags); putdref(db, MKREF(setattr)); lafs_checkpoint_unlock(fs); diff --git a/io.c b/io.c index d59238b..70d5a6f 100644 --- a/io.c +++ b/io.c @@ -55,7 +55,7 @@ lafs_sync_page_io(struct block_device *bdev, sector_t sector, struct completion event; int ret; - rw |= (1 << BIO_RW_UNPLUG); + rw |= REQ_UNPLUG; bio->bi_bdev = bdev; bio->bi_sector = sector; @@ -132,7 +132,7 @@ async_page_io(struct block_device *bdev, sector_t sector, int offset, int size, { struct bio *bio = bio_alloc(GFP_NOIO, 1); - rw |= (1 << BIO_RW_UNPLUG); + rw |= REQ_UNPLUG; bio->bi_bdev = bdev; bio->bi_sector = sector; @@ -187,7 +187,7 @@ void lafs_super_write(struct fs *fs, int dev, u64 addr, char *buf, int size) { struct bio *bio = bio_alloc(GFP_NOIO, 1); - int rw = WRITE | (1 << BIO_RW_UNPLUG); + int rw = WRITE | REQ_UNPLUG; bio->bi_bdev = fs->devs[dev].bdev; bio->bi_sector = addr; diff --git a/lafs.h b/lafs.h index cbdb1b8..1d5bece 100644 --- a/lafs.h +++ b/lafs.h @@ -142,8 +142,7 @@ struct inode *lafs_iget(struct inode *filesys, ino_t inum, int async); struct inode *lafs_iget_fs(struct fs *fs, int fsnum, int inum, int async); int __must_check lafs_import_inode(struct inode *ino, struct datablock *b); void lafs_inode_checkpin(struct inode *ino); -void lafs_clear_inode(struct inode *ino); -void lafs_delete_inode(struct inode *ino); +void lafs_evict_inode(struct inode *ino); void lafs_dirty_inode(struct inode *ino); int lafs_sync_inode(struct inode *ino, int wait); struct inode *lafs_new_inode(struct fs *fs, struct inode *fsys, diff --git a/super.c b/super.c index dcc9f38..478b25d 100644 --- a/super.c +++ b/super.c @@ -768,7 +768,7 @@ static void lafs_kill_sb(struct super_block *sb) for (i = 0; i < fs->devices; i++) { struct fs_dev *dv = &fs->devs[i]; kfree(dv->devblk); - close_bdev_exclusive(dv->bdev, FMODE_READ|FMODE_WRITE); + blkdev_put(dv->bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL); } /* Final checkpoint will have cleared out the leafs lists, @@ -875,9 +875,10 @@ lafs_get_devs(struct fs *fs, struct options *op, int flags) for (i = 0; i < op->devcnt; i++) { struct block_device *bdev; op->curr_dev = i; - - bdev = open_bdev_exclusive(op->devlist[i].dev, - FMODE_READ|FMODE_WRITE, fs); + + bdev = blkdev_get_by_path(op->devlist[i].dev, + FMODE_READ|FMODE_WRITE|FMODE_EXCL, + fs); err = PTR_ERR(bdev); if (IS_ERR(bdev)) goto out; @@ -904,7 +905,7 @@ lafs_get_sb(struct file_system_type *fs_type, * If the later, we return the primary. * If the former, we init the filesystem copying static data * to all supers. - * First we 'open_bdev_exclusive' each device, exclusive to lafs + * First we 'blkdev_get_by_path' each device, exclusive to lafs * Then we 'sget' a superblock that knows any/all the devices. * This may be pre-existing, or may be new * If new, it will be created knowing all devices. @@ -925,7 +926,7 @@ lafs_get_sb(struct file_system_type *fs_type, if (err) goto out; - /* We now have as list of device names. We call open_bdev_exclusive + /* We now have as list of device names. We call blkdev_get_by_path * on each to collect some superblocks. */ err = lafs_get_devs(fs, &op, flags); @@ -979,8 +980,8 @@ out: kfree(op.devlist[i].devblock); kfree(op.devlist[i].stateblock); if (op.devlist[i].bdev) - close_bdev_exclusive(op.devlist[i].bdev, - FMODE_READ|FMODE_WRITE); + blkdev_put(op.devlist[i].bdev, + FMODE_READ|FMODE_WRITE|FMODE_EXCL); } kfree(op.devlist); } @@ -994,7 +995,7 @@ static struct dentry *lafs_get_subset_root(struct inode *ino) struct super_block *sb; int err = 0; struct inode *rootdir, *imapfile; - struct dentry *root; + struct dentry *root = NULL; sb = fs->prime_sb; @@ -1083,6 +1084,7 @@ lafs_get_subset(struct file_system_type *fs_type, if (LAFSI(ino)->type == TypeDir) { struct datablock *inodb; /* maybe convert this to TypeInodeFile */ + err = -EINVAL; if (sb->s_type != &lafs_fs_type) goto out_unlock; if (ino->i_size) @@ -1299,6 +1301,8 @@ void lafs_destroy_inode(struct inode *inode) if (db) { set_bit(I_Destroyed, &LAFSI(inode)->iflags); + if (test_and_clear_bit(B_Async, &db->b.flags)) + lafs_wake_thread(fs_from_inode(inode)); putdref(db, MKREF(destroy)); } else { if (fsys != inode) @@ -1386,28 +1390,6 @@ static int lafs_statfs(struct dentry *de, struct kstatfs *buf) return 0; } -/* FIXME we hold inode_lock while calling drop_inode, so - * extra locking isn't really welcome....??? - */ -static void lafs_drop_inode(struct inode *inode) -{ - struct fs *fs = fs_from_inode(inode); - struct datablock *db; - - /* This lock that we now hold on the inode could prevent - * the cleaner from getting the inode. So after - * the complete the drop we might need to wake the cleaner. - */ - - db = lafs_inode_get_dblock(inode, MKREF(drop)); - - generic_drop_inode(inode); - if (db && test_bit(B_Async, &db->b.flags)) - lafs_wake_thread(fs); - if (db) - putdref(db, MKREF(drop)); -} - static struct super_operations lafs_sops = { .alloc_inode = lafs_alloc_inode, .destroy_inode = lafs_destroy_inode, /* Inverse of 'alloc_inode' */ @@ -1415,13 +1397,8 @@ static struct super_operations lafs_sops = { .dirty_inode = lafs_dirty_inode, /* .write_inode not needed */ /* put_inode ?? */ - .drop_inode = lafs_drop_inode, - /* drop_inode ?? */ /* default will call delete or forget - * where 'forget' flushes and clears - */ - .clear_inode = lafs_clear_inode, /* forget internal state of this inode */ - .delete_inode = lafs_delete_inode, /* remove this inode from filesystem */ + .evict_inode = lafs_evict_inode, .put_super = lafs_put_super, .sync_fs = lafs_sync_fs, /* write_super_lockfs ?? */ diff --git a/test/go b/test/go index 92bd112..59a8dbd 100644 --- a/test/go +++ b/test/go @@ -11,7 +11,7 @@ done rm -f lafs.ko rmmod lafs.ko tftp 10.0.2.2 -m binary -c get /lafs.ko -insmod lafs.ko lafs_trace=0 +insmod lafs.ko lafs_trace=0 || exit 1 #mount -r -t lafs -o 'dev=/dev/sdc' /dev/sdb /mnt/1 mount -t lafs /dev/sdb /mnt/1 #mount -r -t lafs_snap -o snapshot=first /mnt/1 /mnt/2 diff --git a/test/runtty b/test/runtty index e252280..8f64983 100644 --- a/test/runtty +++ b/test/runtty @@ -17,5 +17,5 @@ qemu-kvm -hda hda -hdb $dir/../../code2/fred -hdc $dir/../../code2/frog \ -no-reboot \ -net nic,model=ne2k_pci -net user \ -m 256 -nographic \ - -kernel /home/src/lafs-2.6.34/OBJ/arch/x86/boot/bzImage \ + -kernel /home/src/lafs-2.6.38/OBJ/arch/x86/boot/bzImage \ -append "root=/dev/sda1 console=ttyS0" -tftp /tmp/tftp