Whamcloud - gitweb
- bug fix to unload modules with safe wait functions
[fs/lustre-release.git] / lustre / llite / dir.c
index 12be7a2..1cf2604 100644 (file)
@@ -1,5 +1,4 @@
 /*
- *  linux/fs/ext2/dir.c
  *
  * Copyright (C) 1992, 1993, 1994, 1995
  * Remy Card (card@masi.ibp.fr)
@@ -9,6 +8,7 @@
  *  from
  *
  *  linux/fs/minix/dir.c
+ *  linux/fs/ext2/dir.c
  *
  *  Copyright (C) 1991, 1992  Linus Torvalds
  *
  *  Big-endian to little-endian byte-swapping/bitmaps by
  *        David S. Miller (davem@caip.rutgers.edu), 1995
  *
- * All code that works with directory layout had been switched to pagecache
- * and moved here. AV
+ *  All code that works with directory layout had been switched to pagecache
+ *  and moved here. AV
+ *   
+ *  Adapted for Lustre Light
+ *  Copyright (C) 2002, Cluster File Systems, Inc.
+ * 
  */
 
 #include <linux/fs.h>
 #include <linux/ext2_fs.h>
 #include <linux/pagemap.h>
-#include <linux/obd_support.h>
+#include <linux/mm.h>
 #include <linux/locks.h>
+#include <asm/uaccess.h>
+
+#define DEBUG_SUBSYSTEM S_LLIGHT
+
+#include <linux/obd_support.h>
+#include <linux/lustre_lib.h>
+#include <linux/lustre_idl.h>
+#include <linux/lustre_mds.h>
+#include <linux/lustre_light.h>
 
 typedef struct ext2_dir_entry_2 ext2_dirent;
 
 #define PageChecked(page)        test_bit(PG_checked, &(page)->flags)
 #define SetPageChecked(page)     set_bit(PG_checked, &(page)->flags)
 
+
+static int ll_dir_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
+{
+       return 0;
+}
+
+/* returns the page unlocked, but with a reference */
+static int ll_dir_readpage(struct file *file, struct page *page)
+{
+       struct inode *inode = page->mapping->host;
+        struct ll_sb_info *sbi = ll_i2sbi(inode);
+       char *buf;
+       __u64 offset;
+        int rc = 0;
+       struct ptlrep_hdr *hdr;
+
+        ENTRY;
+
+       if ( ((inode->i_size + PAGE_CACHE_SIZE -1)>>PAGE_SHIFT) 
+            <= page->index) {
+               memset(kmap(page), 0, PAGE_CACHE_SIZE);
+               kunmap(page);
+               goto readpage_out;
+       }
+
+       if (Page_Uptodate(page)) {
+               EXIT;
+               goto readpage_out;
+       }
+
+       offset = page->index << PAGE_SHIFT; 
+       buf = kmap(page);
+        rc = mdc_readpage(&sbi->ll_mds_client, inode->i_ino, S_IFDIR, offset, 
+                         buf, NULL, &hdr);
+       kunmap(page); 
+        if ( rc ) {
+               EXIT; 
+               goto readpage_out;
+        } 
+
+       if ((rc = hdr->status)) {
+               EXIT;
+               goto readpage_out;
+       }
+
+        /* PDEBUG(page, "READ"); */
+
+       SetPageUptodate(page);
+ readpage_out:
+       obd_unlock_page(page);
+        EXIT;
+        return rc;
+} /* ll_dir_readpage */
+
+struct address_space_operations ll_dir_aops = {
+        readpage: ll_dir_readpage,
+        prepare_write: ll_dir_prepare_write
+};
+
 int waitfor_one_page(struct page *page)
 {
        int error = 0;
@@ -67,14 +139,21 @@ static inline unsigned long dir_pages(struct inode *inode)
        return (inode->i_size+PAGE_CACHE_SIZE-1)>>PAGE_CACHE_SHIFT;
 }
 
+extern void set_page_clean(struct page *page); 
+
 static int ext2_commit_chunk(struct page *page, unsigned from, unsigned to)
 {
        struct inode *dir = page->mapping->host;
        int err = 0;
+
        dir->i_version = ++event;
-       page->mapping->a_ops->commit_write(NULL, page, from, to);
-       if (IS_SYNC(dir))
-               err = waitfor_one_page(page);
+       dir->i_size = (page->index << PAGE_CACHE_SHIFT) + to; 
+       SetPageUptodate(page);
+       set_page_clean(page);
+
+       //page->mapping->a_ops->commit_write(NULL, page, from, to);
+       //if (IS_SYNC(dir))
+       //      err = waitfor_one_page(page);
        return err;
 }
 
@@ -91,8 +170,11 @@ static void ext2_check_page(struct page *page)
 
        if ((dir->i_size >> PAGE_CACHE_SHIFT) == page->index) {
                limit = dir->i_size & ~PAGE_CACHE_MASK;
-               if (limit & (chunk_size - 1))
+               if (limit & (chunk_size - 1)) {
+                       CERROR("limit %d dir size %lld index %ld\n", 
+                                       limit, dir->i_size, page->index); 
                        goto Ebadsize;
+               }
                for (offs = limit; offs<PAGE_CACHE_SIZE; offs += chunk_size) {
                        ext2_dirent *p = (ext2_dirent*)(kaddr + offs);
                        p->rec_len = cpu_to_le16(chunk_size);
@@ -124,8 +206,8 @@ out:
        /* Too bad, we had an error */
 
 Ebadsize:
-       printk("ext2_check_page"
-               "size of directory #%lu is not a multiple of chunk size",
+       CERROR("ext2_check_page"
+               "size of directory #%lu is not a multiple of chunk size\n",
                dir->i_ino
        );
        goto fail;
@@ -144,7 +226,7 @@ Espan:
        //Einumber:
        // error = "inode out of bounds";
 bad_entry:
-       printk("ext2_check_page: bad entry in directory #%lu: %s - "
+       CERROR("ext2_check_page: bad entry in directory #%lu: %s - "
                "offset=%lu, inode=%lu, rec_len=%d, name_len=%d",
                dir->i_ino, error, (page->index<<PAGE_CACHE_SHIFT)+offs,
                (unsigned long) le32_to_cpu(p->inode),
@@ -152,7 +234,7 @@ bad_entry:
        goto fail;
 Eend:
        p = (ext2_dirent *)(kaddr + offs);
-       printk("ext2_check_page"
+       CERROR("ext2_check_page"
                "entry in directory #%lu spans the page boundary"
                "offset=%lu, inode=%lu",
                dir->i_ino, (page->index<<PAGE_CACHE_SHIFT)+offs,
@@ -418,7 +500,7 @@ void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de,
 /*
  *     Parent is locked.
  */
-int ext2_add_link (struct dentry *dentry, struct inode *inode)
+int ll_add_link (struct dentry *dentry, struct inode *inode)
 {
        struct inode *dir = dentry->d_parent->d_inode;
        const char *name = dentry->d_name.name;
@@ -449,7 +531,7 @@ int ext2_add_link (struct dentry *dentry, struct inode *inode)
                        name_len = EXT2_DIR_REC_LEN(de->name_len);
                        rec_len = le16_to_cpu(de->rec_len);
                        if ( n==npages && rec_len == 0) {
-                               printk("Fatal dir behaviour\n");
+                               CERROR("Fatal dir behaviour\n");
                                goto out_page;
                        }
                        if (!de->inode && rec_len >= reclen)
@@ -485,8 +567,8 @@ got_it:
        err = ext2_commit_chunk(page, from, to);
 
        // change_inode happens with the commit_chunk
-        // ll_change_inode(dir);
-       /* OFFSET_CACHE */
+       /* XXX OFFSET_CACHE */
+
 out_unlock:
        UnlockPage(page);
 out_page: