Whamcloud - gitweb
Update b_smallfix from HEAD (20040209_1433)
authoradilger <adilger>
Mon, 9 Feb 2004 22:04:18 +0000 (22:04 +0000)
committeradilger <adilger>
Mon, 9 Feb 2004 22:04:18 +0000 (22:04 +0000)
(merge of b_recovery)

lustre/kernel_patches/patches/ext3-mballoc-2.4.24.patch
lustre/smfs/file.c

index 93da5aa..83d638b 100644 (file)
@@ -1,7 +1,7 @@
 Index: linux-2.4.24/fs/ext3/balloc.c
 ===================================================================
 --- linux-2.4.24.orig/fs/ext3/balloc.c 2004-01-10 17:04:42.000000000 +0300
-+++ linux-2.4.24/fs/ext3/balloc.c      2004-02-05 20:35:11.000000000 +0300
++++ linux-2.4.24/fs/ext3/balloc.c      2004-02-06 11:05:42.000000000 +0300
 @@ -11,6 +11,7 @@
   *        David S. Miller (davem@caip.rutgers.edu), 1995
   */
@@ -10,7 +10,7 @@ Index: linux-2.4.24/fs/ext3/balloc.c
  #include <linux/config.h>
  #include <linux/sched.h>
  #include <linux/fs.h>
-@@ -1007,3 +1008,298 @@
+@@ -1007,3 +1008,303 @@
                        bitmap_count);
  }
  #endif
@@ -194,8 +194,6 @@ Index: linux-2.4.24/fs/ext3/balloc.c
 +      struct alloc_status as;
 +      int err, bit, i;
 +
-+      int scaned = 0;
-+
 +      J_ASSERT(num && *num > 0);
 +
 +      if (DQUOT_ALLOC_BLOCK(inode, *num)) {
@@ -214,6 +212,10 @@ Index: linux-2.4.24/fs/ext3/balloc.c
 +      as.len = 0;
 +      as.num = 0;
 +
++      if (goal < le32_to_cpu(es->s_first_data_block) ||
++          goal >= le32_to_cpu(es->s_blocks_count))
++              goal = le32_to_cpu(es->s_first_data_block);
++
 +      lock_super(sb);
 +      first_group = (goal - le32_to_cpu(es->s_first_data_block)) /
 +                      EXT3_BLOCKS_PER_GROUP(sb);
@@ -221,7 +223,6 @@ Index: linux-2.4.24/fs/ext3/balloc.c
 +                      EXT3_BLOCKS_PER_GROUP(sb);
 +      group = first_group;
 +      do {
-+              scaned++;
 +              err = ext3_find_extent_in_group(&as, group, goal, *num);
 +              if (err < 0) 
 +                      goto error_out;
@@ -261,10 +262,14 @@ Index: linux-2.4.24/fs/ext3/balloc.c
 +              goto error_out;
 +      }
 +      bmbh = EXT3_SB(sb)->s_block_bitmap[bitmap_nr];
-+      err = ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh);
++      /* Make sure we use undo access for the bitmap, because it is
++           critical that we do the frozen_data COW on bitmap buffers in
++           all cases even if the buffer is in BJ_Forget state in the
++           committing transaction.  */
++      err = ext3_journal_get_undo_access(handle, bmbh);
 +      if (err)
 +              goto error_out;
-+      err = ext3_journal_get_write_access(handle, bmbh);
++      err = ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh);
 +      if (err)
 +              goto error_out;
 +      err = ext3_journal_get_write_access(handle, bh);
@@ -312,7 +317,7 @@ Index: linux-2.4.24/fs/ext3/balloc.c
 Index: linux-2.4.24/fs/ext3/file.c
 ===================================================================
 --- linux-2.4.24.orig/fs/ext3/file.c   2004-01-31 02:06:18.000000000 +0300
-+++ linux-2.4.24/fs/ext3/file.c        2004-02-05 20:57:07.000000000 +0300
++++ linux-2.4.24/fs/ext3/file.c        2004-02-06 10:20:46.000000000 +0300
 @@ -69,6 +69,18 @@
        int err;
        struct inode *inode = file->f_dentry->d_inode;
@@ -335,7 +340,7 @@ Index: linux-2.4.24/fs/ext3/file.c
 Index: linux-2.4.24/fs/ext3/Makefile
 ===================================================================
 --- linux-2.4.24.orig/fs/ext3/Makefile 2004-02-05 18:44:25.000000000 +0300
-+++ linux-2.4.24/fs/ext3/Makefile      2004-02-05 20:35:11.000000000 +0300
++++ linux-2.4.24/fs/ext3/Makefile      2004-02-06 10:20:46.000000000 +0300
 @@ -14,7 +14,7 @@
  obj-y    := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o iopen.o \
                ioctl.o namei.o super.o symlink.o hash.o ext3-exports.o \
@@ -348,7 +353,7 @@ Index: linux-2.4.24/fs/ext3/Makefile
 Index: linux-2.4.24/include/linux/ext3_fs.h
 ===================================================================
 --- linux-2.4.24.orig/include/linux/ext3_fs.h  2004-01-30 00:09:37.000000000 +0300
-+++ linux-2.4.24/include/linux/ext3_fs.h       2004-02-05 20:35:11.000000000 +0300
++++ linux-2.4.24/include/linux/ext3_fs.h       2004-02-06 10:20:46.000000000 +0300
 @@ -58,6 +58,8 @@
  #define ext3_debug(f, a...)   do {} while (0)
  #endif
index fec85af..e9afdd1 100644 (file)
 #include <linux/pagemap.h>
 #include "smfs_internal.h" 
 
-
 static int smfs_readpage(struct file *file, 
                         struct page *page)
 {
        struct  inode *inode = page->mapping->host;
        struct  inode *cache_inode;
-       int     rc;
-       
+       struct page *cache_page = NULL;
+       int rc = 0; 
+
        ENTRY;
        
        cache_inode = I2CI(inode);
  
         if (!cache_inode)
                 RETURN(-ENOENT);
+       
+       cache_page = grab_cache_page(cache_inode->i_mapping, page->index);
 
-       if (cache_inode->i_mapping->a_ops->readpage)
-               rc = cache_inode->i_mapping->a_ops->readpage(file, page);
-               
-        RETURN(rc);
+       if (!cache_page) 
+               GOTO(exit_release, rc = -ENOMEM);
+
+       if ((rc = cache_inode->i_mapping->a_ops->readpage(file, cache_page)))
+               GOTO(exit_release, 0);
        
+       wait_on_page(cache_page);
+
+       if (!Page_Uptodate(cache_page))
+               GOTO(exit_release, rc = -EIO);
+
+       memcpy(kmap(page), kmap(cache_page), PAGE_CACHE_SIZE);
+
+       flush_dcache_page(page);
+
+       kunmap(cache_page);
+       page_cache_release(cache_page);
+
+exit:  
+       kunmap(page);
+       SetPageUptodate(page);
+       UnlockPage(page);
+
+       RETURN(rc);
+
+exit_release:
+       if (cache_page) 
+               page_cache_release(cache_page);
+       UnlockPage(page);
+       RETURN(rc);
 }
+
 static int smfs_writepage(struct page *page)
 {
 
@@ -52,31 +80,110 @@ static int smfs_writepage(struct page *page)
                rc = cache_inode->i_mapping->a_ops->writepage(page);
                
         RETURN(rc);
-       
 }
+
 struct address_space_operations smfs_file_aops = {
        readpage:   smfs_readpage,
        writepage:  smfs_writepage,
 };
-                                                                                                                                                                                                     
+        
+/* instantiate a file handle to the cache file */
+void smfs_prepare_cachefile(struct inode *inode,
+                           struct file *file, 
+                           struct inode *cache_inode,
+                           struct file *cache_file,
+                           struct dentry *cache_dentry)
+{
+       ENTRY;
+       cache_file->f_pos = file->f_pos;
+        cache_file->f_mode = file->f_mode;
+        cache_file->f_flags = file->f_flags;
+        cache_file->f_count  = file->f_count;
+        cache_file->f_owner  = file->f_owner;
+       cache_file->f_error = file->f_error;
+       cache_file->f_op = inode->i_fop;
+       cache_file->f_dentry = cache_dentry;
+        cache_file->f_dentry->d_inode = cache_inode;
+       cache_file->f_vfsmnt = file->f_vfsmnt;
+       cache_file->private_data = file->private_data;
+       cache_file->f_it = file->f_it;
+       cache_file->f_reada = file->f_reada;
+       cache_file->f_ramax = file->f_ramax;
+       cache_file->f_raend = file->f_raend;
+       cache_file->f_ralen = file->f_ralen;
+       cache_file->f_rawin = file->f_rawin;
+       EXIT;
+}
+/* update file structs*/
+void smfs_update_file(struct file *file, 
+                     struct file *cache_file)
+{
+       ENTRY;
+       file->f_pos = cache_file->f_pos;
+        file->f_mode = cache_file->f_mode;
+        file->f_flags = cache_file->f_flags;
+        file->f_count  = cache_file->f_count;
+        file->f_owner  = cache_file->f_owner;
+       file->f_reada = cache_file->f_reada;
+       file->f_ramax = cache_file->f_ramax;
+       file->f_raend = cache_file->f_raend;
+       file->f_ralen = cache_file->f_ralen;
+       file->f_rawin = cache_file->f_rawin;
+       EXIT;
+}
 
 static ssize_t smfs_write (struct file *filp, const char *buf, 
                           size_t count, loff_t *ppos)
 {
        struct  inode *cache_inode;
        struct  dentry *dentry = filp->f_dentry;
-       int     rc;
+       struct  inode *inode = dentry->d_inode;
+        struct  file open_file;
+       struct  dentry open_dentry;
+       int     rc = 0;
        
        ENTRY;
        
-       cache_inode = I2CI(dentry->d_inode);
+       cache_inode = I2CI(inode);
  
         if (!cache_inode)
                 RETURN(-ENOENT);
-
+       
+       smfs_prepare_cachefile(inode, filp, cache_inode, 
+                              &open_file, &open_dentry);
+       
        if (cache_inode->i_fop->write)
-               cache_inode->i_fop->write(filp, buf, count, ppos);
+               rc = cache_inode->i_fop->write(&open_file, buf, count, &open_file.f_pos);
+       
+       *ppos = open_file.f_pos;
+       duplicate_inode(cache_inode, inode);
+       smfs_update_file(filp, &open_file);
+
+       RETURN(rc);
+}
+int smfs_ioctl(struct inode * inode, struct file * filp, 
+              unsigned int cmd, unsigned long arg)
+{
+       struct  inode *cache_inode;
+       struct  dentry *dentry = filp->f_dentry;
+        struct  file open_file;
+       struct  dentry open_dentry;
+       ssize_t rc;
+       
+       ENTRY;
+       
+       cache_inode = I2CI(dentry->d_inode);
+        if (!cache_inode)
+                RETURN(-ENOENT);
+
+       smfs_prepare_cachefile(inode, filp, cache_inode, 
+                              &open_file, &open_dentry);
+       
+       if (cache_inode->i_fop->ioctl)
+               rc = cache_inode->i_fop->ioctl(cache_inode, &open_file, cmd, arg);
                
+       duplicate_inode(cache_inode, inode);
+       smfs_update_file(filp, &open_file);
         RETURN(rc);
 }
 
@@ -85,26 +192,179 @@ static ssize_t smfs_read (struct file *filp, char *buf,
 {
        struct  inode *cache_inode;
        struct  dentry *dentry = filp->f_dentry;
+       struct  inode *inode = dentry->d_inode;
+        struct  file open_file;
+       struct  dentry open_dentry;
        ssize_t rc;
        
        ENTRY;
        
        cache_inode = I2CI(dentry->d_inode);
         if (!cache_inode)
                 RETURN(-ENOENT);
 
+       smfs_prepare_cachefile(inode, filp, cache_inode, 
+                              &open_file, &open_dentry);
+       
        if (cache_inode->i_fop->read)
-               rc = cache_inode->i_fop->read(filp, buf, count, ppos);
+               rc = cache_inode->i_fop->read(&open_file, buf, count, &open_file.f_pos);
+    
+       *ppos = open_file.f_pos;
+       duplicate_inode(cache_inode, inode);
+       smfs_update_file(filp, &open_file);
+       RETURN(rc);
+}
+
+static loff_t smfs_llseek(struct file *file, 
+                         loff_t offset, 
+                         int origin)
+{
+       struct  inode *cache_inode;
+       struct  dentry *dentry = file->f_dentry;
+        struct  file open_file;
+       struct  dentry open_dentry;
+       ssize_t rc;
+       
+       ENTRY;
+       
+       cache_inode = I2CI(dentry->d_inode);
+        if (!cache_inode)
+                RETURN(-ENOENT);
+
+       smfs_prepare_cachefile(dentry->d_inode, file, cache_inode, 
+                              &open_file, &open_dentry);
+       
+       if (cache_inode->i_fop->llseek)
+               rc = cache_inode->i_fop->llseek(&open_file, offset, origin);
+       
+       duplicate_inode(cache_inode, dentry->d_inode);
+       smfs_update_file(file, &open_file);
                
         RETURN(rc);
 }
 
+static int smfs_mmap(struct file * file, struct vm_area_struct * vma)
+{
+       struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
+        struct inode *inode = mapping->host;
+        struct inode *cache_inode = NULL;
+        struct  file open_file;
+       struct  dentry open_dentry;
+       int    rc = 0;
+
+       cache_inode = I2CI(inode);
+        if (!cache_inode)
+                RETURN(-ENOENT);
+
+       smfs_prepare_cachefile(inode, file, cache_inode, 
+                              &open_file, &open_dentry);
+       
+       if (cache_inode->i_fop->mmap)
+               rc = cache_inode->i_fop->mmap(&open_file, vma);
+       
+       duplicate_inode(cache_inode, inode);
+       smfs_update_file(file, &open_file);
+       
+       RETURN(rc);
+}
+
+static int smfs_open(struct inode * inode, struct file * filp)
+{
+       struct inode *cache_inode = NULL;
+        struct  file open_file;
+       struct  dentry open_dentry;
+       int    rc = 0;
+
+       cache_inode = I2CI(inode);
+        if (!cache_inode)
+                RETURN(-ENOENT);
+
+       smfs_prepare_cachefile(inode, filp, cache_inode, 
+                              &open_file, &open_dentry);
+       
+       if (cache_inode->i_fop->open)
+               rc = cache_inode->i_fop->open(cache_inode, &open_file);
+        
+       duplicate_inode(cache_inode, inode);
+       smfs_update_file(filp, &open_file);
+       
+       RETURN(rc);
+
+}
+static int smfs_release(struct inode * inode, struct file * filp)
+{
+       struct inode *cache_inode = NULL;
+        struct  file open_file;
+       struct  dentry open_dentry;
+       int    rc = 0;
+
+       cache_inode = I2CI(inode);
+        if (!cache_inode)
+                RETURN(-ENOENT);
+       
+       smfs_prepare_cachefile(inode, filp, cache_inode, 
+                              &open_file, &open_dentry);
+
+       if (cache_inode->i_fop->release)
+               rc = cache_inode->i_fop->release(cache_inode, &open_file);
+
+       duplicate_inode(cache_inode, inode);
+       smfs_update_file(filp, &open_file);
+        
+       RETURN(rc);
+}
+int smfs_fsync(struct file * file, 
+                     struct dentry *dentry, 
+                     int datasync)
+{
+       struct inode *inode = dentry->d_inode;
+       struct inode *cache_inode;
+        struct  file open_file;
+       struct  dentry open_dentry;
+       int    rc = 0;
+
+       cache_inode = I2CI(inode);
+        if (!cache_inode)
+                RETURN(-ENOENT);
+       
+       smfs_prepare_cachefile(inode, file, cache_inode, 
+                              &open_file, &open_dentry);
+
+       if (cache_inode->i_fop->fsync)
+               rc = cache_inode->i_fop->fsync(&open_file, &open_dentry, datasync);
+       
+       duplicate_inode(cache_inode, inode);
+       smfs_update_file(file, &open_file);
+       
+       RETURN(rc);
+}
+
 struct file_operations smfs_file_fops = {
-       read:   smfs_read,
-       write:  smfs_write,
+       llseek:         smfs_llseek,
+       read:           smfs_read,
+       write:          smfs_write,
+       ioctl:          smfs_ioctl,
+       mmap:           smfs_mmap,
+       open:           smfs_open,
+       release:        smfs_release,
+       fsync:          smfs_fsync,
 };
 
+static void smfs_prepare_cache_dentry(struct dentry *dentry, struct inode *inode)
+{
+       atomic_set(&dentry->d_count, 1);
+       dentry->d_vfs_flags = 0;
+       dentry->d_flags = 0;
+       dentry->d_inode = inode;
+       dentry->d_op = NULL;
+       dentry->d_fsdata = NULL;
+       dentry->d_mounted = 0;
+       INIT_LIST_HEAD(&dentry->d_hash);
+       INIT_LIST_HEAD(&dentry->d_lru);
+       INIT_LIST_HEAD(&dentry->d_subdirs);
+       INIT_LIST_HEAD(&dentry->d_alias);
+}
+
 static void smfs_truncate(struct inode * inode)      
 {
        struct  inode *cache_inode;
@@ -117,29 +377,114 @@ static void smfs_truncate(struct inode * inode)
        if (cache_inode->i_op->truncate)
                cache_inode->i_op->truncate(cache_inode);
 
-       duplicate(inode, cache_inode);          
+       duplicate_inode(inode, cache_inode);            
         
        return; 
 } 
  
-static int smfs_setattr(struct dentry *dentry, struct iattr *attr)      
+int smfs_setattr(struct dentry *dentry, struct iattr *attr)      
+{
+       struct  inode *cache_inode;
+       struct  dentry open_dentry;
+
+       int     rc = 0;
+
+       cache_inode = I2CI(dentry->d_inode);
+
+       if (!cache_inode) 
+               RETURN(-ENOENT);
+       smfs_prepare_cache_dentry(&open_dentry, cache_inode);
+       
+       if (cache_inode->i_op->setattr)
+               rc = cache_inode->i_op->setattr(&open_dentry, attr);
+
+       RETURN(rc);
+} 
+  
+int smfs_setxattr(struct dentry *dentry, const char *name,
+                 const void *value, size_t size, int flags)
 {
        struct  inode *cache_inode;
+       struct  dentry open_dentry;
        int     rc = 0;
 
        cache_inode = I2CI(dentry->d_inode);
 
        if (!cache_inode) 
                RETURN(-ENOENT);
+
+       smfs_prepare_cache_dentry(&open_dentry, cache_inode);
        
        if (cache_inode->i_op->setattr)
-               rc = cache_inode->i_op->setattr(dentry, attr);
+               rc = cache_inode->i_op->setxattr(&open_dentry, name, value, size, flags);
 
        RETURN(rc);
 } 
-                                                                                                                                                                                     
+                        
+int smfs_getxattr(struct dentry *dentry, const char *name,
+                 void *buffer, size_t size)
+{
+       struct  inode *cache_inode;
+       struct  dentry open_dentry;
+       int     rc = 0;
+
+       cache_inode = I2CI(dentry->d_inode);
+
+       if (!cache_inode) 
+               RETURN(-ENOENT);
+
+       smfs_prepare_cache_dentry(&open_dentry, cache_inode);
+       
+       if (cache_inode->i_op->setattr)
+               rc = cache_inode->i_op->getxattr(&open_dentry, name, buffer, size);
+
+       RETURN(rc);
+}
+
+ssize_t smfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
+{
+       struct  inode *cache_inode;
+       struct  dentry open_dentry;
+       int     rc = 0;
+
+       cache_inode = I2CI(dentry->d_inode);
+
+       if (!cache_inode) 
+               RETURN(-ENOENT);
+
+       smfs_prepare_cache_dentry(&open_dentry, cache_inode);
+       
+       if (cache_inode->i_op->listxattr)
+               rc = cache_inode->i_op->listxattr(&open_dentry, buffer, size);
+
+       RETURN(rc);
+}                                                                                                                                                           
+
+int smfs_removexattr(struct dentry *dentry, const char *name)
+{
+       struct  inode *cache_inode;
+       struct  dentry open_dentry;
+       int     rc = 0;
+
+       cache_inode = I2CI(dentry->d_inode);
+
+       if (!cache_inode) 
+               RETURN(-ENOENT);
+
+       smfs_prepare_cache_dentry(&open_dentry, cache_inode);
+       
+       if (cache_inode->i_op->removexattr)
+               rc = cache_inode->i_op->removexattr(&open_dentry, name);
+
+       RETURN(rc);
+}
+
 struct inode_operations smfs_file_iops = {
        truncate:       smfs_truncate,          /* BKL held */
         setattr:        smfs_setattr,           /* BKL held */
+        setxattr:       smfs_setxattr,          /* BKL held */
+        getxattr:       smfs_getxattr,          /* BKL held */
+        listxattr:      smfs_listxattr,         /* BKL held */
+        removexattr:    smfs_removexattr,       /* BKL held */
 };