Whamcloud - gitweb
obdfs/*.c: finished truncate implementation
authoradilger <adilger>
Tue, 7 Mar 2000 15:59:16 +0000 (15:59 +0000)
committeradilger <adilger>
Tue, 7 Mar 2000 15:59:16 +0000 (15:59 +0000)
lustre/obdfs/file.c
lustre/obdfs/flushd.c
lustre/obdfs/namei.c
lustre/obdfs/rw.c
lustre/obdfs/super.c

index 87d6b0e..decec1a 100644 (file)
@@ -105,7 +105,7 @@ struct inode_operations obdfs_file_inode_operations = {
        NULL,                   /* get_block */
        obdfs_readpage,         /* readpage */
        obdfs_writepage,        /* writepage */
-       NULL /* XXX add XXX */, /* truncate */
+       obdfs_truncate,         /* truncate */
        NULL,                   /* permission */
        NULL                    /* revalidate */
 };
index 5d8367e..f13952c 100644 (file)
@@ -8,27 +8,9 @@
  *
  */
 #define __NO_VERSION__
-#include <linux/module.h>
-#include <linux/sched.h>
 #include <linux/fs.h>
-#include <linux/malloc.h>
 #include <linux/locks.h>
-#include <linux/errno.h>
 #include <linux/swap.h>
-#include <linux/smp_lock.h>
-#include <linux/vmalloc.h>
-#include <linux/blkdev.h>
-#include <linux/sysrq.h>
-#include <linux/file.h>
-#include <linux/init.h>
-#include <linux/quotaops.h>
-#include <linux/iobuf.h>
-#include <linux/highmem.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/bitops.h>
-#include <asm/mmu_context.h>
 
 #include <linux/obd_support.h>
 #include <linux/obd_class.h>
@@ -118,6 +100,43 @@ static int obdfs_enqueue_pages(struct inode *inode, struct obdo **obdo,
        return num;  
 } /* obdfs_enqueue_pages */
 
+/* Dequeue cached pages for a dying inode without writing them to disk. */
+void obdfs_dequeue_pages(struct inode *inode)
+{
+       struct list_head *tmp;
+
+       obd_down(&obdfs_i2sbi(inode)->osi_list_mutex);
+       tmp = obdfs_islist(inode);
+       if ( list_empty(tmp) ) {
+               CDEBUG(D_INFO, "no dirty pages for inode %ld\n", inode->i_ino);
+               obd_up(&obdfs_i2sbi(inode)->osi_list_mutex);
+               EXIT;
+               return;
+       }
+
+       /* take it out of the super list */
+       list_del(tmp);
+       INIT_LIST_HEAD(obdfs_islist(inode));
+
+       tmp = obdfs_iplist(inode);
+       while ( (tmp = tmp->prev) != obdfs_iplist(inode) ) {
+               struct obdfs_pgrq *req;
+               struct page *page;
+               
+               req = list_entry(tmp, struct obdfs_pgrq, rq_plist);
+               page = req->rq_page;
+               /* take it out of the list and free */
+               obdfs_pgrq_del(req);
+               /* now put the page away */
+               put_page(page);
+       }
+
+       obd_up(&obdfs_i2sbi(inode)->osi_list_mutex);
+
+       /* decrement inode reference for page cache */
+       inode->i_count--;
+}
+
 /* Remove writeback requests for the superblock */
 int obdfs_flush_reqs(struct list_head *inode_list, unsigned long check_time)
 {
@@ -147,8 +166,7 @@ int obdfs_flush_reqs(struct list_head *inode_list, unsigned long check_time)
 
        obd_down(&sbi->osi_list_mutex);
        if ( list_empty(inode_list) ) {
-               CDEBUG(D_CACHE, "list empty: memory %ld, inodes %d, pages %d\n",
-                      obd_memory, obd_inodes, obd_pages);
+               CDEBUG(D_CACHE, "list empty: memory %ld\n", obd_memory);
                obd_up(&sbi->osi_list_mutex);
                EXIT;
                return 0;
@@ -348,34 +366,35 @@ static int pupdate(void *unused)
                /* asynchronous setattr etc for the future ...
                obdfs_flush_dirty_inodes(jiffies - pupd_prm.age_super);
                 */
+               /* XXX for debugging
                dirty_limit = nr_free_buffer_pages() * pupd_prm.nfract / 100;
-               CDEBUG(D_CACHE, "dirty_limit %ld, cache_count %ld\n",
-                      dirty_limit, obdfs_cache_count);
+                * XXX */
+               dirty_limit = 16384 * pupd_prm.nfract / 100;
+               CDEBUG(D_CACHE, "dirty_limit %ld, cache_count %ld, wrote %d\n",
+                      dirty_limit, obdfs_cache_count, wrote);
 
                if (obdfs_cache_count > dirty_limit) {
                        interval = 0;
                        if ( wrote < pupd_prm.ndirty )
                                age >>= 1;
+                       CDEBUG(D_CACHE, "age %ld, interval %d\n",
+                               age, interval);
                } else {
-                       int isave = interval;
-                       int asave = age;
-
-                       if ( wrote < pupd_prm.ndirty >> 1 )
+                       if ( wrote < pupd_prm.ndirty >> 1 &&
+                            obdfs_cache_count < dirty_limit / 2) {
                                interval = pupd_prm.interval;
-                       else
-                               interval = isave >> 1;
-
-                       if (obdfs_cache_count > dirty_limit / 3) {
-                               age = asave >> 1;
-                               interval = isave >> 1;
-                       } else
                                age = pupd_prm.age_buffer;
+                       } else if (obdfs_cache_count > dirty_limit / 2) {
+                               interval >>= 1;
+                               if ( wrote < pupd_prm.ndirty )
+                                       age >>= 1;
+                               CDEBUG(D_CACHE, "age %ld, interval %d\n",
+                                      age, interval);
+                       }
                }
 
-               CDEBUG(D_CACHE, "age %ld, interval %d\n", age, interval);
                wrote = obdfs_flush_dirty_pages(jiffies - age);
        }
-
 }
 
 
index fcf50cb..c3f12e0 100644 (file)
@@ -457,6 +457,11 @@ static struct inode *obdfs_new_inode(struct inode *dir, int mode)
        int err;
 
        ENTRY;
+       if (IOPS(dir, create) == NULL) {
+               printk(KERN_ERR __FUNCTION__ ": no create method!\n");
+               EXIT;
+               return ERR_PTR(-EIO);
+       }
        oa = obdo_alloc();
        if (!oa) {
                EXIT;
index 56adb90..be52f79 100644 (file)
@@ -47,6 +47,12 @@ static int obdfs_brw(int rw, struct inode *inode, struct page *page, int create)
        int              err;
 
        ENTRY;
+       if (IOPS(inode, brw) == NULL) {
+               printk(KERN_ERR __FUNCTION__ ": no brw method!\n");
+               EXIT;
+               return -EIO;
+       }
+
        oa = obdo_fromid(IID(inode), inode->i_ino, OBD_MD_FLNOTOBD);
        if ( IS_ERR(oa) ) {
                EXIT;
@@ -218,11 +224,15 @@ int obdfs_do_vec_wr(struct inode **inodes, obd_count num_io,
                    obd_count *oa_bufs, struct page **pages, char **bufs,
                    obd_size *counts, obd_off *offsets, obd_flag *flags)
 {
-       struct super_block *sb = inodes[0]->i_sb;
-       struct obdfs_sb_info *sbi = (struct obdfs_sb_info *)&sb->u.generic_sbp;
        int err;
 
        ENTRY;
+       if (IOPS(inodes[0], brw) == NULL) {
+               printk(KERN_ERR __FUNCTION__ ": no brw method!\n");
+               EXIT;
+               return -EIO;
+       }
+
        CDEBUG(D_INFO, "writing %d page(s), %d obdo(s) in vector\n",
               num_io, num_obdos);
        { /* DEBUGGING */
@@ -237,8 +247,8 @@ int obdfs_do_vec_wr(struct inode **inodes, obd_count num_io,
                printk("\n");
        }
 
-       err = OPS(sb, brw)(WRITE, &sbi->osi_conn, num_obdos, obdos, oa_bufs,
-                               bufs, counts, offsets, flags);
+       err = IOPS(inodes[0], brw)(WRITE, IID(inodes[0]), num_obdos, obdos,
+                                 oa_bufs, bufs, counts, offsets, flags);
 
        CDEBUG(D_CACHE, "BRW done\n");
        /* release the pages from the page cache */
@@ -384,7 +394,7 @@ int obdfs_write_one_page(struct file *file, struct page *page,
        if (copy_from_user((u8*)page_address(page) + offset, buf, bytes))
                return -EFAULT;
 
-       lock_kernel(); /* XXX do we really need to lock the kernel to write? */
+       lock_kernel();
        err = obdfs_writepage(file->f_dentry, page);
        unlock_kernel();
 
@@ -457,3 +467,47 @@ struct page *obdfs_getpage(struct inode *inode, unsigned long offset,
 } /* obdfs_getpage */
 
 
+void obdfs_truncate(struct inode *inode)
+{
+       struct obdo *oa;
+       int err;
+       ENTRY;
+
+       obdfs_dequeue_pages(inode);
+
+       if (IOPS(inode, punch) == NULL) {
+               printk(KERN_ERR __FUNCTION__ ": no punch method!\n");
+               EXIT;
+               return;
+       }
+       oa = obdo_alloc();
+       if ( !oa ) {
+               /* XXX This would give an inconsistent FS, so deal with it as
+                * best we can for now - an obdo on the stack is not pretty.
+                */
+               struct obdo obdo;
+
+               printk(__FUNCTION__ ": obdo_alloc failed - using stack!\n");
+
+               obdo.o_valid = OBD_MD_FLNOTOBD;
+               obdfs_from_inode(&obdo, inode);
+
+               err = IOPS(inode, punch)(IID(inode), &obdo, obdo.o_size, 0);
+       } else {
+               oa->o_valid = OBD_MD_FLNOTOBD;
+               obdfs_from_inode(oa, inode);
+
+               CDEBUG(D_PUNCH, "calling punch for %ld (%Lu bytes at 0)\n",
+                      (long)oa->o_id, oa->o_size);
+               err = IOPS(inode, punch)(IID(inode), oa, oa->o_size, 0);
+
+               obdo_free(oa);
+       }
+
+       if (err) {
+               printk(__FUNCTION__ ": obd_truncate fails (%d)\n", err);
+               EXIT;
+               return;
+       }
+       EXIT;
+}
index 972b27b..f092c88 100644 (file)
@@ -320,6 +320,11 @@ static void obdfs_write_inode(struct inode *inode)
        int err;
        
        ENTRY;
+       if (IOPS(inode, setattr) == NULL) {
+               printk(KERN_ERR __FUNCTION__ ": no setattr method!\n");
+               EXIT;
+               return;
+       }
        oa = obdo_alloc();
        if ( !oa ) {
                printk(__FUNCTION__ ": obdo_alloc failed\n");
@@ -346,54 +351,21 @@ static void obdfs_write_inode(struct inode *inode)
 } /* obdfs_write_inode */
 
 
-/* Dequeue cached pages for a dying inode without writing them to disk.
- *
- * This routine is called from iput() (for each unlink on the inode).
- * We can't put this code into delete_inode() since that is called only
+/* This routine is called from iput() (for each unlink on the inode).
+ * We can't put this call into delete_inode() since that is called only
  * when i_count == 0, and we need to keep a reference on the inode while
  * it is in the page cache, which means i_count > 0.  Catch 22.
  */
 static void obdfs_put_inode(struct inode *inode)
 {
-       struct list_head *tmp;
-
        ENTRY;
        if (inode->i_nlink) {
                EXIT;
                return;
        }
 
-       obd_down(&obdfs_i2sbi(inode)->osi_list_mutex);
-       tmp = obdfs_islist(inode);
-       if ( list_empty(tmp) ) {
-               CDEBUG(D_INFO, "no dirty pages for inode %ld\n", inode->i_ino);
-               obd_up(&obdfs_i2sbi(inode)->osi_list_mutex);
-               EXIT;
-               return;
-       }
-
-       /* take it out of the super list */
-       list_del(tmp);
-       INIT_LIST_HEAD(obdfs_islist(inode));
-
-       tmp = obdfs_iplist(inode);
-       while ( (tmp = tmp->prev) != obdfs_iplist(inode) ) {
-               struct obdfs_pgrq *req;
-               struct page *page;
-               
-               req = list_entry(tmp, struct obdfs_pgrq, rq_plist);
-               page = req->rq_page;
-               /* take it out of the list and free */
-               obdfs_pgrq_del(req);
-               /* now put the page away */
-               put_page(page);
-       }
-
-       /* decrement inode reference for page cache */
-       inode->i_count--;
-
+       obdfs_dequeue_pages(inode);
        EXIT;
-       obd_up(&obdfs_i2sbi(inode)->osi_list_mutex);
 } /* obdfs_put_inode */
 
 
@@ -401,11 +373,18 @@ static void obdfs_delete_inode(struct inode *inode)
 {
        struct obdo *oa;
        int err;
+
         ENTRY;
+       if (IOPS(inode, destroy) == NULL) {
+               printk(KERN_ERR __FUNCTION__ ": no destroy method!\n");
+               EXIT;
+               return;
+       }
 
        oa = obdo_alloc();
        if ( !oa ) {
                printk(__FUNCTION__ ": obdo_alloc failed\n");
+               EXIT;
                return;
        }
        oa->o_valid = OBD_MD_FLNOTOBD;
@@ -431,6 +410,11 @@ static int obdfs_notify_change(struct dentry *de, struct iattr *attr)
        int err;
 
        ENTRY;
+       if (IOPS(inode, setattr) == NULL) {
+               printk(KERN_ERR __FUNCTION__ ": no setattr method!\n");
+               EXIT;
+               return -EIO;
+       }
        oa = obdo_alloc();
        if ( !oa ) {
                printk(__FUNCTION__ ": obdo_alloc failed\n");
@@ -528,8 +512,7 @@ void cleanup_module(void)
        obdfs_sysctl_clean();
        obdfs_cleanup_pgrqcache();
        unregister_filesystem(&obdfs_fs_type);
-       CDEBUG(D_MALLOC, "OBDFS mem used %ld, inodes %d, pages %d\n",
-              obd_memory, obd_inodes, obd_pages);
+       CDEBUG(D_MALLOC, "OBDFS mem used %ld\n", obd_memory);
        EXIT;
 }