Whamcloud - gitweb
- elimininate the system calls from filter obd
[fs/lustre-release.git] / lustre / llite / super.c
index d788210..9c13cc6 100644 (file)
 #include <linux/obd_class.h>
 #include <linux/lustre_light.h>
 
-//struct list_head ll_super_list;
 extern struct address_space_operations ll_aops;
+extern struct address_space_operations ll_dir_aops;
 struct super_operations ll_super_operations;
-long ll_cache_count = 0;
-long ll_mutex_start = 0;
 long obd_memory = 0;
 
 static char *ll_read_opt(const char *opt, char *data)
 {
         char *value;
         char *retval;
+       ENTRY;
 
         CDEBUG(D_INFO, "option: %s, data %s\n", opt, data);
-        if ( strncmp(opt, data, strlen(opt)) )
+        if ( strncmp(opt, data, strlen(opt)) ) {
+               EXIT;
                 return NULL;
-
-        if ( (value = strchr(data, '=')) == NULL )
+       }
+        if ( (value = strchr(data, '=')) == NULL ) {
+               EXIT;
                 return NULL;
+       }
 
         value++;
         OBD_ALLOC(retval, char *, strlen(value) + 1);
@@ -63,15 +65,19 @@ static char *ll_read_opt(const char *opt, char *data)
         
         memcpy(retval, value, strlen(value)+1);
         CDEBUG(D_PSDEV, "Assigned option: %s, value %s\n", opt, retval);
+       EXIT;
         return retval;
 }
 
 static void ll_options(char *options, char **dev, char **vers)
 {
         char *this_char;
+       ENTRY; 
 
-        if (!options)
+        if (!options) { 
+               EXIT;
                 return;
+       }
 
         for (this_char = strtok (options, ",");
              this_char != NULL;
@@ -82,6 +88,7 @@ static void ll_options(char *options, char **dev, char **vers)
                         continue;
                 
         }
+       EXIT;
 }
 
 static struct super_block * ll_read_super(struct super_block *sb, 
@@ -89,254 +96,141 @@ static struct super_block * ll_read_super(struct super_block *sb,
 {
         struct inode *root = 0; 
         struct ll_sb_info *sbi = (struct ll_sb_info *)(&sb->u.generic_sbp);
-        struct obd_device *obddev;
        char *device = NULL;
         char *version = NULL;
-       int root_ino = 2;
        int connected = 0;
         int devno;
         int err;
        struct mds_rep *rep; 
-       struct mds_rep_hdr *hdr = NULL; 
-        
+       struct ptlrep_hdr *hdr = NULL; 
 
         ENTRY;
         MOD_INC_USE_COUNT; 
+
         memset(sbi, 0, sizeof(*sbi));
-        
-        CDEBUG(D_INFO, "\n"); 
+
         ll_options(data, &device, &version);
+       printk(__FUNCTION__ "line %d\n", __LINE__); 
         if ( !device ) {
                 printk(__FUNCTION__ ": no device\n");
-                EXIT;
+               sb = NULL; 
                 goto ERR;
         }
 
        devno = simple_strtoul(device, NULL, 0);
-        CDEBUG(D_INFO, "\n"); 
         if ( devno >= MAX_OBD_DEVICES ) {
-                printk(__FUNCTION__ ": device of %s too high (%d)\n", device, devno);
-                EXIT;
+                printk(__FUNCTION__ ": device of %s too high\n", device);
+               sb = NULL; 
                 goto ERR;
         } 
 
-        CDEBUG(D_INFO, "\n"); 
-
-        obddev = &obd_dev[devno];
-        sbi->ll_obd = obddev;
-        sbi->ll_ops = sbi->ll_obd->obd_type->typ_ops;
-        sbi->ll_conn.oc_dev = obddev;
-        CDEBUG(D_INFO, "\n"); 
-
+        sbi->ll_conn.oc_dev = &obd_dev[devno];
         err = obd_connect(&sbi->ll_conn);
-        CDEBUG(D_INFO, "\n"); 
         if ( err ) {
-                printk("OBDFS: cannot connect to %s\n", device);
-                EXIT;
+                printk(__FUNCTION__ "cannot connect to %s\n", device);
+               sb = NULL; 
                 goto ERR;
         }
        connected = 1;
 
-        CDEBUG(D_INFO, "\n"); 
-        /* list of dirty inodes, and a mutex to hold while modifying it */
-        INIT_LIST_HEAD(&sbi->ll_inodes);
-        init_MUTEX (&sbi->ll_list_mutex);
+       err = kportal_uuid_to_peer("mds", &sbi->ll_peer);
+       if (err == 0)
+               sbi->ll_peer_ptr = &sbi->ll_peer;
 
-        CDEBUG(D_INFO, "\n"); 
         sbi->ll_super = sb;
        sbi->ll_rootino = 2;
-        
-        CDEBUG(D_INFO, "\n"); 
+
        sb->s_maxbytes = 1LL << 36;
-       printk("Max bytes: %Lx\n", sb->s_maxbytes);
         sb->s_blocksize = PAGE_SIZE;
         sb->s_blocksize_bits = (unsigned char)PAGE_SHIFT;
         sb->s_magic = LL_SUPER_MAGIC;
         sb->s_op = &ll_super_operations;
+       printk(__FUNCTION__ "line %d\n", __LINE__); 
 
         /* make root inode */
-        CDEBUG(D_INFO, "\n"); 
-       err = mdc_getattr(root_ino, S_IFDIR, OBD_MD_FLNOTOBD|OBD_MD_FLBLOCKS, 
-                        &rep, &hdr);
+       err = mdc_getattr(sbi->ll_peer_ptr, sbi->ll_rootino, S_IFDIR, 
+                         OBD_MD_FLNOTOBD|OBD_MD_FLBLOCKS, 
+                         &rep, &hdr);
         if (err) {
-                printk(__FUNCTION__ ": mds_getattr failed %d\n", err);
-               iput(root); 
-               if (rep)
-                       kfree(rep);
-                EXIT;
+                printk(__FUNCTION__ ": mds_getattr failed for root %d\n", err);
+               sb = NULL; 
                 goto ERR;
         }
                          
-        CDEBUG(D_INFO, "mode %o\n", rep->mode);
-        CDEBUG(D_INFO, "\n"); 
-        root = iget4(sb, root_ino, NULL, rep);
-       kfree(hdr);
-        CDEBUG(D_INFO, "\n"); 
-        if (!root) {
-            printk("OBDFS: bad iget4 for root\n");
-            sb->s_dev = 0;
-            err = -ENOENT;
-            EXIT;
+        root = iget4(sb, sbi->ll_rootino, NULL, rep);
+        if (root) {
+               sb->s_root = d_alloc_root(root);
+       } else {
+            printk("lustre_light: bad iget4 for root\n");
+           sb = NULL; 
             goto ERR;
         } 
         
-        sb->s_root = d_alloc_root(root);
-       //        list_add(&sbi->ll_list, &ll_super_list);
-        OBD_FREE(device, strlen(device) + 1);
-        if (version)
-                OBD_FREE(version, strlen(version) + 1);
-        EXIT;  
-        return sb;
-
 ERR:
-        MOD_DEC_USE_COUNT;
+       if (hdr)
+               kfree(hdr);
         if (device)
                 OBD_FREE(device, strlen(device) + 1);
         if (version)
                 OBD_FREE(version, strlen(version) + 1);
-       if (connected) 
-               sbi->ll_ops->o_disconnect(&sbi->ll_conn);
+       if (!sb && connected) 
+               obd_disconnect(&sbi->ll_conn);
 
-        if (sbi) {
-                sbi->ll_super = NULL;
-        }
-        if (root) {
+        if (!sb && root) {
                 iput(root);
         }
-        sb->s_dev = 0;
-        return NULL;
-} /* ll_read_super */
+       if (!sb) 
+               MOD_DEC_USE_COUNT;
 
+       EXIT;
+        return sb;
+} /* ll_read_super */
 
 static void ll_put_super(struct super_block *sb)
 {
-        struct ll_sb_info *sbi;
-
         ENTRY;
-        sb->s_dev = 0;
-        
-        sbi = (struct ll_sb_info *) &sb->u.generic_sbp;
-        //ll_flush_reqs(&sbi->ll_inodes, ~0UL);
 
-        OPS(sb,disconnect)(ID(sb));
-        list_del(&sbi->ll_list);
-        
-        printk(KERN_INFO "OBDFS: Bye bye.\n");
+        obd_disconnect(ID(sb));
 
         MOD_DEC_USE_COUNT;
         EXIT;
 } /* ll_put_super */
 
 
-void ll_do_change_inode(struct inode *inode, int valid)
-{
-        struct obdo *oa;
-        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");
-                EXIT;
-                return;
-        }
-
-        oa->o_valid = OBD_MD_FLNOTOBD & (valid | OBD_MD_FLID);
-        ll_from_inode(oa, inode);
-       oa->o_mode = inode->i_mode;
-        err = IOPS(inode, setattr)(IID(inode), oa);
-
-        if ( err )
-                printk(__FUNCTION__ ": obd_setattr fails (%d)\n", err);
-
-        EXIT;
-        obdo_free(oa);
-} /* ll_write_inode */
-
-void ll_change_inode(struct inode *inode, int mask)
-{
-       return ll_do_change_inode(inode, OBD_MD_FLNLINK); 
-}
-
-
-extern void write_inode_pages(struct inode *);
-/* 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 ll_put_inode(struct inode *inode)
+extern inline struct obdo * ll_oa_from_inode(struct inode *inode, int valid);
+static void ll_delete_inode(struct inode *inode)
 {
-        ENTRY;
-        if (inode->i_nlink && (atomic_read(&inode->i_count) == 1)) {
-               write_inode_pages(inode);
-                EXIT;
-                return;
-        }
-
-        //ll_dequeue_pages(inode);
-        EXIT;
-} /* ll_put_inode */
 
+       if (S_ISREG(inode->i_mode)) { 
+               int err; 
+               struct obdo *oa; 
+               oa = ll_oa_from_inode(inode, OBD_MD_FLNOTOBD);
+               if (!oa) { 
+                       printk(__FUNCTION__ ": no memory\n"); 
+               }
+
+               err = obd_destroy(IID(inode), oa); 
+               printk(__FUNCTION__  ": obd destroy of %Ld error %d\n", 
+                      oa->o_id, err);
+               obdo_free(oa);
+       }
 
-static void ll_delete_inode(struct inode *inode)
-{
-       ll_do_change_inode(inode, ~0);
        clear_inode(inode); 
 }
-#if 0
-{
-        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;
-        ll_from_inode(oa, inode);
-
-       /* XXX how do we know that this inode is now clean? */
-       printk("delete_inode ------> link %d\n", inode->i_nlink);
-        ODEBUG(oa);
-        err = IOPS(inode, destroy)(IID(inode), oa);
-        obdo_free(oa);
-        clear_inode(inode);
-        if (err) {
-                printk(__FUNCTION__ ": obd_destroy fails (%d)\n", err);
-                EXIT;
-                return;
-        }
 
-        EXIT;
-} /* ll_delete_inode */
-#endif
-
-
-static int ll_attr2inode(struct inode * inode, struct iattr * attr)
+/* like inode_setattr, but doesn't mark the inode dirty */ 
+static int ll_attr2inode(struct inode * inode, struct iattr * attr, int trunc)
 {
        unsigned int ia_valid = attr->ia_valid;
        int error = 0;
 
-       if (ia_valid & ATTR_SIZE) {
+       if ((ia_valid & ATTR_SIZE) && trunc ) {
                error = vmtruncate(inode, attr->ia_size);
                if (error)
                        goto out;
-       }
+       } else if (ia_valid & ATTR_SIZE) { 
+               inode->i_size = attr->ia_size;
+       }               
 
        if (ia_valid & ATTR_UID)
                inode->i_uid = attr->ia_uid;
@@ -357,39 +251,29 @@ out:
        return error;
 }
 
-int ll_setattr(struct dentry *de, struct iattr *attr)
+int ll_inode_setattr(struct inode *inode, struct iattr *attr, int do_trunc)
 {
-        struct inode *inode = de->d_inode;
-        struct obdo *oa;
-        int err;
+       struct ptlrep_hdr *hdr = NULL;
+        struct ll_sb_info *sbi = ll_i2sbi(inode);
+       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");
-                return -ENOMEM;
-        }
 
-       ll_attr2inode(inode, attr);
-        oa->o_id = inode->i_ino;
-       oa->o_mode = inode->i_mode;
-        obdo_from_iattr(oa, attr);
-        err = IOPS(inode, setattr)(IID(inode), oa);
+       /* change incore inode */
+       ll_attr2inode(inode, attr, do_trunc);
 
+       err = mdc_setattr(sbi->ll_peer_ptr, inode, attr, NULL, &hdr); 
         if ( err )
-                printk(__FUNCTION__ ": obd_setattr fails (%d)\n", err);
+                printk(__FUNCTION__ ": ll_setattr fails (%d)\n", err);
 
         EXIT;
-        obdo_free(oa);
         return err;
-} /* ll_setattr */
-
+}
 
+int ll_setattr(struct dentry *de, struct iattr *attr)
+{
+       return ll_inode_setattr(de->d_inode, attr, 1);
+}
 
 static int ll_statfs(struct super_block *sb, struct statfs *buf)
 {
@@ -398,7 +282,7 @@ static int ll_statfs(struct super_block *sb, struct statfs *buf)
 
         ENTRY;
 
-        err = OPS(sb,statfs)(ID(sb), &tmp);
+        err = obd_statfs(ID(sb), &tmp);
         if ( err ) { 
                 printk(__FUNCTION__ ": obd_statfs fails (%d)\n", err);
                 return err;
@@ -410,6 +294,56 @@ static int ll_statfs(struct super_block *sb, struct statfs *buf)
         return err; 
 }
 
+static void inline ll_to_inode(struct inode *dst, struct mds_rep *rep)
+{
+       struct ll_inode_info *ii = 
+               (struct ll_inode_info *) &dst->u.generic_ip;
+
+       /* core attributes first */
+        if ( rep->valid & OBD_MD_FLID )
+                dst->i_ino = rep->ino;
+        if ( rep->valid & OBD_MD_FLATIME ) 
+                dst->i_atime = rep->atime;
+        if ( rep->valid & OBD_MD_FLMTIME ) 
+                dst->i_mtime = rep->mtime;
+        if ( rep->valid & OBD_MD_FLCTIME ) 
+                dst->i_ctime = rep->ctime;
+        if ( rep->valid & OBD_MD_FLSIZE ) 
+                dst->i_size = rep->size;
+        if ( rep->valid & OBD_MD_FLMODE ) 
+                dst->i_mode = rep->mode;
+        if ( rep->valid & OBD_MD_FLUID ) 
+                dst->i_uid = rep->uid;
+        if ( rep->valid & OBD_MD_FLGID ) 
+                dst->i_gid = rep->gid;
+        if ( rep->valid & OBD_MD_FLFLAGS ) 
+                dst->i_flags = rep->flags;
+        if ( rep->valid & OBD_MD_FLNLINK )
+                dst->i_nlink = rep->nlink;
+        if ( rep->valid & OBD_MD_FLGENER )
+                dst->i_generation = rep->generation;
+
+       /* this will become more elaborate for striping etc */ 
+       if (rep->valid & OBD_MD_FLOBJID) 
+               ii->lli_objid = rep->objid;
+#if 0
+
+        if (obdo_has_inline(oa)) {
+               if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) ||
+                   S_ISFIFO(inode->i_mode)) {
+                       obd_rdev rdev = *((obd_rdev *)oa->o_inline);
+                       CDEBUG(D_INODE,
+                              "copying device %x from obdo to inode\n", rdev);
+                       init_special_inode(inode, inode->i_mode, rdev);
+               } else {
+                       CDEBUG(D_INFO, "copying inline from obdo to inode\n");
+                       memcpy(oinfo->lli_inline, oa->o_inline, OBD_INLINESZ);
+               }
+                oinfo->lli_flags |= OBD_FL_INLINEDATA;
+        }
+#endif 
+} /* ll_to_inode */
+
 static inline void ll_read_inode2(struct inode *inode, void *opaque)
 {
        struct mds_rep *rep = opaque; 
@@ -417,9 +351,6 @@ static inline void ll_read_inode2(struct inode *inode, void *opaque)
        ENTRY;
        ll_to_inode(inode, rep); 
 
-        INIT_LIST_HEAD(ll_iplist(inode)); /* list of dirty pages on inode */
-        INIT_LIST_HEAD(ll_islist(inode)); /* list of inodes in superblock */
-
         /* OIDEBUG(inode); */
 
         if (S_ISREG(inode->i_mode)) {
@@ -430,15 +361,10 @@ static inline void ll_read_inode2(struct inode *inode, void *opaque)
         } else if (S_ISDIR(inode->i_mode)) {
                 inode->i_op = &ll_dir_inode_operations;
                 inode->i_fop = &ll_dir_operations; 
-                inode->i_mapping->a_ops = &ll_aops;
+                inode->i_mapping->a_ops = &ll_dir_aops;
                 EXIT;
         } else if (S_ISLNK(inode->i_mode)) {
-                if (inode->i_blocks) { 
-                        inode->i_op = &ll_symlink_inode_operations;
-                        inode->i_mapping->a_ops = &ll_aops;
-                }else {
-                        inode->i_op = &ll_fast_symlink_inode_operations;
-                }
+               inode->i_op = &ll_fast_symlink_inode_operations;
                 EXIT;
         } else {
                 init_special_inode(inode, inode->i_mode,
@@ -453,14 +379,11 @@ static inline void ll_read_inode2(struct inode *inode, void *opaque)
 struct super_operations ll_super_operations =
 {
        read_inode2: ll_read_inode2,
-       // put_inode: ll_put_inode,
-        // delete_inode: ll_delete_inode,
-        // put_super: ll_put_super,
+        delete_inode: ll_delete_inode,
+        put_super: ll_put_super,
         // statfs: ll_statfs
 };
 
-
-
 struct file_system_type lustre_light_fs_type = {
    "lustre_light", 0, ll_read_super, NULL
 };