Whamcloud - gitweb
obdfs/*.c: fixed bug with flushing of cache of deleted obdo
authoradilger <adilger>
Fri, 25 Feb 2000 06:34:22 +0000 (06:34 +0000)
committeradilger <adilger>
Fri, 25 Feb 2000 06:34:22 +0000 (06:34 +0000)
lustre/obdfs/dir.c
lustre/obdfs/file.c
lustre/obdfs/flushd.c
lustre/obdfs/rw.c
lustre/obdfs/super.c
lustre/obdfs/symlink.c
lustre/obdfs/sysctl.c

index ab5174d..7c8f96a 100644 (file)
@@ -60,8 +60,7 @@ struct file_operations obdfs_dir_operations = {
        NULL,                   /* no special release code */
        NULL,                   /* fsync */
        NULL,                   /* fasync */
-       NULL,                   /* check_media_change */
-       NULL                    /* revalidate */
+       NULL                    /* lock */
 };
 
 struct inode_operations obdfs_dir_inode_operations = {
index b41f54f..1bbb190 100644 (file)
@@ -85,8 +85,7 @@ struct file_operations obdfs_file_operations = {
        NULL,                   /* no special release code */
        NULL,                   /* fsync */
        NULL,                   /* fasync */
-       NULL,                   /* check_media_change */
-       NULL                    /* revalidate */
+       NULL                    /* lock */
 };
 
 struct inode_operations obdfs_file_inode_operations = {
index ba1c1cb..0a47e7f 100644 (file)
@@ -111,39 +111,6 @@ static int obdfs_enqueue_pages(struct inode *inode, struct obdo **obdo,
        return num;  
 } /* obdfs_enqueue_pages */
 
-/* dequeue requests for a dying inode */
-void obdfs_dequeue_reqs(struct inode *inode)
-{
-
-       struct list_head *tmp;
-
-       obd_down(&obdfs_i2sbi(inode)->osi_list_mutex);
-       tmp = obdfs_islist(inode);
-       if ( list_empty(tmp) ) {
-               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->next) != 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);
-} /* obdfs_dequeue_reqs */
-
 /* Remove writeback requests for the superblock */
 int obdfs_flush_reqs(struct list_head *inode_list, int check_time)
 {
@@ -162,9 +129,7 @@ int obdfs_flush_reqs(struct list_head *inode_list, int check_time)
        int               err = 0;
        struct obdfs_sb_info *sbi;
 
-
        ENTRY;
-
        if (!inode_list) {
                CDEBUG(D_INODE, "no list\n");
                EXIT;
@@ -270,7 +235,8 @@ int obdfs_flush_reqs(struct list_head *inode_list, int check_time)
                               inode->i_ino);
                        tmp = tmp->prev;
                        list_del(obdfs_islist(inode));
-                       iput(inode);
+                       /* decrement inode reference for page cache */
+                       inode->i_count--;
                        INIT_LIST_HEAD(obdfs_islist(inode));
                }
        }
@@ -280,7 +246,7 @@ int obdfs_flush_reqs(struct list_head *inode_list, int check_time)
        EXIT;
 ERR:
        return err;
-} /* obdfs_remove_pages_from_cache */
+} /* obdfs_flush_reqs */
 
 
 void obdfs_flush_dirty_pages(int check_time)
@@ -297,7 +263,7 @@ void obdfs_flush_dirty_pages(int check_time)
                obdfs_flush_reqs(&sbi->osi_inodes, check_time);
        }
        EXIT;
-}
+} /* obdfs_flush_dirty_pages */
 
 
 static struct task_struct *pupdated;
index 91f270f..5bd837e 100644 (file)
@@ -283,9 +283,16 @@ static int obdfs_add_page_to_cache(struct inode *inode, struct page *page)
 
        /* If inode isn't already on the superblock inodes list, add it,
         * and increase ref count on inode so it doesn't disappear on us.
+        *
+        * We increment the reference count on the inode to keep it from
+        * being freed from memory.  This _should_ be an iget() with an
+        * iput() in both flush_reqs() and put_inode(), but since ut_inode()
+        * is called from iput() we can't call iput() again there.  Instead
+        * we just increment/decrement i_count, which is essentially what
+        * iget/iput do for an inode already in memory.
         */
        if ( list_empty(obdfs_islist(inode)) ) {
-               iget(inode->i_sb, inode->i_ino);
+               inode->i_count++;
                CDEBUG(D_INODE, "adding inode %ld to superblock list %p\n",
                       inode->i_ino, obdfs_slist(inode));
                list_add(obdfs_islist(inode), obdfs_slist(inode));
@@ -314,7 +321,7 @@ int obdfs_do_writepage(struct inode *inode, struct page *page, int sync)
                err = obdfs_brw(WRITE, inode, page, 1);
        else {
                err = obdfs_add_page_to_cache(inode, page);
-               CDEBUG(D_IOCTL, "DO_WR ino: %ld, page %p, err %d, uptodata %d\n", inode->i_ino, page, err, Page_Uptodate(page));
+               CDEBUG(D_IOCTL, "DO_WR ino: %ld, page %p, err %d, uptodate %d\n", inode->i_ino, page, err, Page_Uptodate(page));
        }
                
        if ( !err )
index 2358705..3fe0f78 100644 (file)
 #include <linux/obd_class.h>
 #include <linux/obdfs.h>
 
-/* VFS super_block ops */
-static struct super_block *obdfs_read_super(struct super_block *, void *, int);
-static int  obdfs_notify_change(struct dentry *dentry, struct iattr *attr);
-static void obdfs_write_inode(struct inode *);
-static void obdfs_delete_inode(struct inode *);
-static void obdfs_put_super(struct super_block *);
-static int obdfs_statfs(struct super_block *sb, struct statfs *buf, 
-                      int bufsiz);
-
-/* exported operations */
-struct super_operations obdfs_super_operations =
-{
-       obdfs_read_inode,       /* read_inode */
-       obdfs_write_inode,      /* write_inode */
-       NULL,                   /* put_inode */
-       obdfs_delete_inode,     /* delete_inode */
-       obdfs_notify_change,    /* notify_change */
-       obdfs_put_super,        /* put_super */
-       NULL,                   /* write_super */
-       obdfs_statfs,           /* statfs */
-       NULL                    /* remount_fs */
-};
-
 struct list_head obdfs_super_list;
+struct super_operations obdfs_super_operations;
 
 static char *obdfs_read_opt(const char *opt, char *data)
 {
@@ -81,7 +59,7 @@ static char *obdfs_read_opt(const char *opt, char *data)
        return retval;
 }
 
-void obdfs_options(char *options, char **dev, char **vers)
+static void obdfs_options(char *options, char **dev, char **vers)
 {
        char *this_char;
 
@@ -123,7 +101,6 @@ static int obdfs_getdev(char *devpath, int *dev)
 }
 
 
-/* XXX allocate a super_entry, and add the super to the obdfs_super_list */
 static struct super_block * obdfs_read_super(struct super_block *sb, 
                                            void *data, int silent)
 {
@@ -265,7 +242,7 @@ ERR:
         }
         sb->s_dev = 0;
         return NULL;
-}
+} /* obdfs_read_super */
 
 
 static void obdfs_put_super(struct super_block *sb)
@@ -290,7 +267,7 @@ static void obdfs_put_super(struct super_block *sb)
 
 
 /* all filling in of inodes postponed until lookup */
-void obdfs_read_inode(struct inode *inode)
+static void obdfs_read_inode(struct inode *inode)
 {
        struct obdo *oa;
 
@@ -361,6 +338,58 @@ 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
+ * 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_INODE, __FUNCTION__ ": 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->next) != 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--;
+
+       EXIT;
+       obd_up(&obdfs_i2sbi(inode)->osi_list_mutex);
+} /* obdfs_put_inode */
+
+
 static void obdfs_delete_inode(struct inode *inode)
 {
        struct obdo *oa;
@@ -375,9 +404,6 @@ static void obdfs_delete_inode(struct inode *inode)
        oa->o_valid = OBD_MD_FLNOTOBD;
        obdfs_from_inode(oa, inode);
 
-       /* free the cache pages that might be hangning around */
-       obdfs_dequeue_reqs(inode);
-
        err = IOPS(inode, destroy)(IID(inode), oa);
        obdo_free(oa);
 
@@ -445,6 +471,20 @@ static int obdfs_statfs(struct super_block *sb, struct statfs *buf,
        return err; 
 }
 
+/* exported operations */
+struct super_operations obdfs_super_operations =
+{
+       obdfs_read_inode,       /* read_inode */
+       obdfs_write_inode,      /* write_inode */
+       obdfs_put_inode,        /* put_inode */
+       obdfs_delete_inode,     /* delete_inode */
+       obdfs_notify_change,    /* notify_change */
+       obdfs_put_super,        /* put_super */
+       NULL,                   /* write_super */
+       obdfs_statfs,           /* statfs */
+       NULL                    /* remount_fs */
+};
+
 struct file_system_type obdfs_fs_type = {
    "obdfs", 0, obdfs_read_super, NULL
 };
index 7aa2959..f1e0a5d 100644 (file)
@@ -30,8 +30,8 @@
 #include <linux/obd_support.h> /* for ENTRY and EXIT only */
 #include <linux/obdfs.h>
 
-/* static */
-struct dentry * obdfs_follow_link(struct dentry * dentry, struct dentry *base,
+static struct dentry * obdfs_follow_link(struct dentry * dentry,
+                                        struct dentry *base,
                                         unsigned int follow)
 {
        struct inode *inode = dentry->d_inode;
@@ -60,8 +60,7 @@ struct dentry * obdfs_follow_link(struct dentry * dentry, struct dentry *base,
        return base;
 }
 
-/* static */
-int obdfs_readlink (struct dentry * dentry, char * buffer, int buflen)
+static int obdfs_readlink (struct dentry * dentry, char * buffer, int buflen)
 {
        struct inode *inode = dentry->d_inode;
        struct page *page = NULL;
index 6b1752d..4970ce3 100644 (file)
@@ -14,7 +14,7 @@
 
 struct ctl_table_header *obdfs_table_header = NULL;
 
-int obdfs_debug_level = 4095;
+int obdfs_debug_level = 0;
 int obdfs_print_entry = 1;