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_
/* 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))
}
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;
}
/* 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);
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)
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);
struct completion event;
int ret;
- rw |= (1 << BIO_RW_UNPLUG);
+ rw |= REQ_UNPLUG;
bio->bi_bdev = bdev;
bio->bi_sector = sector;
{
struct bio *bio = bio_alloc(GFP_NOIO, 1);
- rw |= (1 << BIO_RW_UNPLUG);
+ rw |= REQ_UNPLUG;
bio->bi_bdev = bdev;
bio->bi_sector = sector;
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;
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,
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,
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;
* 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.
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);
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);
}
struct super_block *sb;
int err = 0;
struct inode *rootdir, *imapfile;
- struct dentry *root;
+ struct dentry *root = NULL;
sb = fs->prime_sb;
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)
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)
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' */
.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 ?? */
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
-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