Whamcloud - gitweb
Numerous fixes, including the attach code, better page locking etc.
[fs/lustre-release.git] / lustre / obdfs / rw.c
index 389058c..ff06852 100644 (file)
@@ -45,14 +45,14 @@ int obdfs_readpage(struct file *file, struct page *page)
 
        /* XXX flush stuff */
        sbi = sb->u.generic_sbp;
-       PDEBUG(page, READ);
+       PDEBUG(page, "READ");
        rc =  sbi->osi_ops->o_brw(READ, sbi->osi_conn_info.conn_id, 
-                     file->f_dentry->d_inode->i_ino, page);
+                     file->f_dentry->d_inode->i_ino, page, 0);
        if (rc == PAGE_SIZE ) {
                SetPageUptodate(page);
                UnlockPage(page);
        } 
-       PDEBUG(page, READ);
+       PDEBUG(page, "READ");
        if ( rc == PAGE_SIZE ) 
                rc = 0;
        return rc;
@@ -71,10 +71,22 @@ int obdfs_readpage(struct file *file, struct page *page)
 int obdfs_write_one_page(struct file *file, struct page *page, unsigned long offset, unsigned long bytes, const char * buf)
 {
        long status;
-
+        struct obdfs_sb_info *sbi = file->f_dentry->d_inode->i_sb->u.generic_sbp;
+
+       if ( !Page_Uptodate(page) ) {
+               status =  sbi->osi_ops->o_brw(READ, 
+                                             sbi->osi_conn_info.conn_id, 
+                                             file->f_dentry->d_inode->i_ino, 
+                                             page, 1);
+               if (status == PAGE_SIZE ) {
+                       SetPageUptodate(page);
+               } else { 
+                       return status;
+               }
+       }
        bytes -= copy_from_user((u8*)page_address(page) + offset, buf, bytes);
        status = -EFAULT;
-       CDEBUG(D_INODE, "page offset %ld, bytes %ld, offset %ld, page addr %lx, writing: %s, beg of page %s\n", page->offset, bytes, offset, page_address(page), ((char *) page_address(page)) + offset, (char *)page_address(page));
+
        if (bytes) {
                lock_kernel();
                status = obdfs_writepage(file, page);
@@ -92,19 +104,17 @@ int obdfs_write_one_page(struct file *file, struct page *page, unsigned long off
 /* returns the page unlocked, but with a reference */
 int obdfs_writepage(struct file *file, struct page *page)
 {
-        struct obdfs_sb_info *sbi;
-       struct super_block *sb = file->f_dentry->d_inode->i_sb;
+        struct obdfs_sb_info *sbi = file->f_dentry->d_inode->i_sb->u.generic_sbp;
        int rc;
 
         ENTRY;
-       PDEBUG(page,WRITE);
+       PDEBUG(page, "WRITEPAGE");
        /* XXX flush stuff */
-       sbi = sb->u.generic_sbp;
 
        rc = sbi->osi_ops->o_brw(WRITE, sbi->osi_conn_info.conn_id, 
-                     file->f_dentry->d_inode->i_ino, page);
+                     file->f_dentry->d_inode->i_ino, page, 1);
        SetPageUptodate(page);
-       PDEBUG(page,WRITE);
+       PDEBUG(page,"WRITEPAGE");
        return rc;
 }
 
@@ -113,7 +123,7 @@ int obdfs_writepage(struct file *file, struct page *page)
    page is returned unlocked, with the up to date flag set, 
    and held, i.e. caller must do a page_put
 */
-struct page *obdfs_getpage(struct inode *inode, unsigned long offset)
+struct page *obdfs_getpage(struct inode *inode, unsigned long offset, int create, int locked)
 {
        unsigned long new_page;
        struct page ** hash;
@@ -125,9 +135,11 @@ struct page *obdfs_getpage(struct inode *inode, unsigned long offset)
 
        sbi = sb->u.generic_sbp;
        
-       page = find_get_page(inode, offset); 
+       page = find_lock_page(inode, offset); 
        if (page && Page_Uptodate(page)) { 
-               PDEBUG(page,READ);
+               PDEBUG(page,"GETPAGE");
+               if (!locked)
+                       UnlockPage(page);
                return page;
        } 
                
@@ -143,13 +155,16 @@ struct page *obdfs_getpage(struct inode *inode, unsigned long offset)
        /* corresponding struct page in the mmap */
        hash = page_hash(inode, offset);
        page = page_cache_entry(new_page);
+       PDEBUG(page, "GETPAGE");
        if (!add_to_page_cache_unique(page, inode, offset, hash)) {
                CDEBUG(D_INODE, "Page not found. Reading it.\n");
-               PDEBUG(page,READ);
+               PDEBUG(page,"GETPAGE");
                sbi->osi_ops->o_brw(READ, sbi->osi_conn_info.conn_id, 
-                                   inode->i_ino, page);
-               UnlockPage(page);
+                                   inode->i_ino, page, create);
+               if ( !locked )
+                       UnlockPage(page);
                SetPageUptodate(page);
+               PDEBUG(page,"GETPAGE");
                return page;
        }
        /*
@@ -157,13 +172,13 @@ struct page *obdfs_getpage(struct inode *inode, unsigned long offset)
         * raced with us and added our page to the cache first.
         */
        CDEBUG(D_INODE, "Page not found. Someone raced us.\n");
-       PDEBUG(page,READ);
+       PDEBUG(page,"GETPAGE");
        return page;
 }
 
 
 
-struct file_operations obdfs_file_operations = {
+struct file_operations obdfs_file_ops = {
        NULL,                   /* lseek - default */
        generic_file_read,      /* read */
        obdfs_file_write,     /* write - bad */
@@ -181,16 +196,16 @@ struct file_operations obdfs_file_operations = {
 };
 
 struct inode_operations obdfs_inode_ops = {
-       &obdfs_file_operations, /* default directory file-ops */
-       NULL,           /* create */
+       &obdfs_file_ops,        /* default directory file-ops */
+       obdfs_create,   /* create */
        obdfs_lookup,   /* lookup */
-       NULL,           /* link */
-       NULL,           /* unlink */
-       NULL,           /* symlink */
-       NULL,           /* mkdir */
-       NULL,           /* rmdir */
-       NULL,           /* mknod */
-       NULL,           /* rename */
+       obdfs_link,     /* link */
+       obdfs_unlink,   /* unlink */
+       obdfs_symlink,  /* symlink */
+       obdfs_mkdir,    /* mkdir */
+       obdfs_rmdir,    /* rmdir */
+       obdfs_mknod,    /* mknod */
+       obdfs_rename,   /* rename */
        NULL,           /* readlink */
        NULL,           /* follow_link */
        NULL,           /* get_block */