Whamcloud - gitweb
Add open/close methods for filterobd.
[fs/lustre-release.git] / lustre / obdfilter / filter.c
index 2e805a8..ec8c0cb 100644 (file)
@@ -54,13 +54,13 @@ static void filter_id(char *buf, obd_id id, obd_mode mode)
 }
 
 /* setup the object store with correct subdirectories */
-static void filter_prep(struct obd_device *obddev)
+static int filter_prep(struct obd_device *obddev)
 {
         struct obd_run_ctxt saved;
         struct file *file;
         struct inode *inode;
         loff_t off;
-        long rc;
+        int rc = 0;
         char rootid[128];
         __u64 lastino = 2;
 
@@ -68,10 +68,10 @@ static void filter_prep(struct obd_device *obddev)
         rc = simple_mkdir(current->fs->pwd, "O", 0700);
         rc = simple_mkdir(current->fs->pwd, "P", 0700);
         rc = simple_mkdir(current->fs->pwd, "D", 0700);
-        file  = filp_open("O", O_RDONLY, 0); 
-        if (!file || IS_ERR(file)) { 
-                CERROR("cannot open O\n"); 
-                goto out;
+        file = filp_open("O", O_RDONLY, 0);
+        if (IS_ERR(file)) {
+                CERROR("cannot open O\n");
+                GOTO(out, rc = PTR_ERR(file));
         }
         rc = simple_mkdir(file->f_dentry, "R", 0700);  /* regular */
         rc = simple_mkdir(file->f_dentry, "D", 0700);  /* directory */
@@ -80,21 +80,22 @@ static void filter_prep(struct obd_device *obddev)
         rc = simple_mkdir(file->f_dentry, "B", 0700);  /* block devices */
         rc = simple_mkdir(file->f_dentry, "F", 0700);  /* fifo's */
         rc = simple_mkdir(file->f_dentry, "S", 0700);  /* sockets */
-        filp_close(file, NULL); 
+        filp_close(file, NULL);
 
         filter_id(rootid, FILTER_ROOTINO, S_IFDIR);
         file = filp_open(rootid, O_RDWR | O_CREAT, 00755);
         if (IS_ERR(file)) {
                 CERROR("OBD filter: cannot make root directory"); 
-                goto out;
+                GOTO(out, rc = PTR_ERR(file));
         }
         filp_close(file, 0);
+        /* FIXME: this is the same as the _file_ we just created? */
         rc = simple_mkdir(current->fs->pwd, rootid, 0755);
 
         file = filp_open("D/status", O_RDWR | O_CREAT, 0700);
         if ( !file || IS_ERR(file) ) {
                 CERROR("OBD filter: cannot open/create status file\n");
-                goto out;
+                GOTO(out, rc = PTR_ERR(file));
         }
 
         /* steal operations */
@@ -104,26 +105,29 @@ static void filter_prep(struct obd_device *obddev)
         obddev->u.filter.fo_aops = inode->i_mapping->a_ops;
 
         off = 0;
-        if (inode->i_size == 0) { 
-                rc = file->f_op->write(file, (char *)&lastino, 
-                                       sizeof(lastino), &off);
-                if (rc != sizeof(lastino)) { 
+        if (inode->i_size == 0) {
+                ssize_t retval = file->f_op->write(file, (char *)&lastino,
+                                                   sizeof(lastino), &off);
+                if (retval != sizeof(lastino)) {
                         CERROR("OBD filter: error writing lastino\n");
-                        goto out;
+                        GOTO(out, rc = -EIO);
                 }
-        } else { 
-                rc = file->f_op->read(file, (char *)&lastino, sizeof(lastino), 
-                                      &off);
-                if (rc != sizeof(lastino)) { 
+        } else {
+                ssize_t retval = file->f_op->read(file, (char *)&lastino,
+                                                  sizeof(lastino), &off);
+                if (retval != sizeof(lastino)) {
                         CERROR("OBD filter: error reading lastino\n");
-                        goto out;
+                        GOTO(out, rc = -EIO);
                 }
         }
         obddev->u.filter.fo_lastino = lastino;
         filp_close(file, 0); 
 
+        rc = 0;
  out:
         pop_ctxt(&saved);
+
+        return(rc);
 }
 
 /* cleanup the filter: write last used object id to status file */
@@ -259,29 +263,23 @@ static int filter_disconnect(struct obd_conn *conn)
 }
 
 /* mount the file system (secretly) */
-static int filter_setup(struct obd_device *obddev, obd_count len,
-                        void *buf)
-                        
+static int filter_setup(struct obd_device *obddev, obd_count len, void *buf)
 {
         struct obd_ioctl_data* data = buf;
         struct vfsmount *mnt;
-        int err
+        int err = 0;
         ENTRY;
-        
-        
-        mnt = do_kern_mount(data->ioc_inlbuf2, 0, 
-                            data->ioc_inlbuf1, NULL); 
+
+        MOD_INC_USE_COUNT;
+        mnt = do_kern_mount(data->ioc_inlbuf2, 0, data->ioc_inlbuf1, NULL);
         err = PTR_ERR(mnt);
-        if (IS_ERR(mnt)) { 
-                EXIT;
-                return err;
-        }
+        if (IS_ERR(mnt))
+                GOTO(err_dec, err);
 
+        /* XXX is this even possible if do_kern_mount succeeded? */
         obddev->u.filter.fo_sb = mnt->mnt_root->d_inode->i_sb;
-        if (!obddev->u.filter.fo_sb) {
-                EXIT;
-                return -ENODEV;
-        }
+        if (!obddev->u.filter.fo_sb)
+                GOTO(err_put, err = -ENODEV);
 
         obddev->u.filter.fo_vfsmnt = mnt;
         obddev->u.filter.fo_fstype = strdup(data->ioc_inlbuf2);
@@ -290,13 +288,25 @@ static int filter_setup(struct obd_device *obddev, obd_count len,
         obddev->u.filter.fo_ctxt.pwd = mnt->mnt_root;
         obddev->u.filter.fo_ctxt.fs = KERNEL_DS;
 
-        filter_prep(obddev);
+        err = filter_prep(obddev);
+        if (err)
+                GOTO(err_kfree, err);
         spin_lock_init(&obddev->u.filter.fo_lock);
 
-        MOD_INC_USE_COUNT;
-        EXIT; 
-        return 0;
-} 
+        RETURN(0);
+
+err_kfree:
+        kfree(obddev->u.filter.fo_fstype);
+err_put:
+        unlock_kernel();
+        mntput(obddev->u.filter.fo_vfsmnt);
+        obddev->u.filter.fo_sb = 0;
+        lock_kernel();
+
+err_dec:
+        MOD_DEC_USE_COUNT;
+        return err;
+}
 
 
 static int filter_cleanup(struct obd_device * obddev)
@@ -305,22 +315,18 @@ static int filter_cleanup(struct obd_device * obddev)
 
         ENTRY;
 
-        if ( !(obddev->obd_flags & OBD_SET_UP) ) {
-                EXIT;
-                return 0;
-        }
+        if ( !(obddev->obd_flags & OBD_SET_UP) )
+                RETURN(0);
 
         if ( !list_empty(&obddev->obd_gen_clients) ) {
                 CERROR("still has clients!\n");
-                EXIT;
-                return -EBUSY;
+                RETURN(-EBUSY);
         }
 
         sb = obddev->u.filter.fo_sb;
-        if (!obddev->u.filter.fo_sb){
-                EXIT;
-                return 0;
-        }
+        if (!obddev->u.filter.fo_sb)
+                RETURN(0);
+
         filter_post(obddev);
 
         unlock_kernel();
@@ -331,8 +337,7 @@ static int filter_cleanup(struct obd_device * obddev)
         lock_kernel();
 
         MOD_DEC_USE_COUNT;
-        EXIT;
-        return 0;
+        RETURN(0);
 }
 
 
@@ -357,7 +362,7 @@ static inline void filter_from_inode(struct obdo *oa, struct inode *inode)
         }
 
 #if 0
else if (ext2obd_has_inline(inode)) {
       else if (filter_has_inline(inode)) {
                 CDEBUG(D_INFO, "copying inline from inode to obdo\n");
                 memcpy(oa->o_inline, inode->u.ext2_i.i_data,
                        MIN(sizeof(inode->u.ext2_i.i_data),OBD_INLINESZ));
@@ -365,7 +370,7 @@ static inline void filter_from_inode(struct obdo *oa, struct inode *inode)
                 oa->o_valid |= OBD_MD_FLINLINE;
         }
 
-        if (ext2obd_has_obdmd(inode)) {
+        if (filter_has_obdmd(inode)) {
                 /* XXX this will change when we don't store the obdmd in data */
                 CDEBUG(D_INFO, "copying obdmd from inode to obdo\n");
                 memcpy(oa->o_obdmd, inode->u.ext2_i.i_data,
@@ -435,6 +440,38 @@ static int filter_setattr(struct obd_conn *conn, struct obdo *oa)
         return rc;
 }
 
+static int filter_open(struct obd_conn *conn, struct obdo *oa)
+{
+        struct inode *inode;
+        /* ENTRY; */
+
+        if (!gen_client(conn))
+                RETURN(-EINVAL);
+
+        if ( !(inode = filter_inode_from_obj(conn->oc_dev,
+                                             oa->o_id, oa->o_mode)) )
+                RETURN(-ENOENT);
+
+        return 0;
+} /* filter_open */
+
+static int filter_close(struct obd_conn *conn, struct obdo *oa)
+{
+        struct inode *inode;
+        /* ENTRY; */
+
+        if (!gen_client(conn))
+                RETURN(-EINVAL);
+
+        if ( !(inode = filter_inode_from_obj(conn->oc_dev,
+                                             oa->o_id, oa->o_mode)) )
+                RETURN(-ENOENT);
+
+        iput(inode);  /* for the close */
+        iput(inode);  /* for this call */
+        return 0;
+} /* filter_close */
+
 static int filter_create (struct obd_conn* conn, struct obdo *oa)
 {
         char name[64];
@@ -606,7 +643,7 @@ static int filter_write(struct obd_conn *conn, struct obdo *oa, char *buf,
         }
 
         return err;
-} /* ext2obd_write */
+} /* filter_write */
 
 static int filter_pgcache_brw(int rw, struct obd_conn *conn, 
                                obd_count num_oa,
@@ -729,100 +766,78 @@ struct inode *ioobj_to_inode(struct obd_conn *conn, struct obd_ioobj *o)
         return inode;
 }
 
-int filter_preprw(int cmd, struct obd_conn *conn, 
-                   int objcount, struct obd_ioobj *obj, 
-                   int niocount, struct niobuf *nb, 
-                   struct niobuf *res)
+static int filter_preprw(int cmd, struct obd_conn *conn,
+                         int objcount, struct obd_ioobj *obj,
+                         int niocount, struct niobuf *nb,
+                         struct niobuf *res)
 {
-        int i, j; 
-        struct obd_ioobj *o;
-        struct niobuf *b;
-        struct niobuf *r;
-        struct inode *inode;
-        struct page *page;
-        int rc = 0;
+        struct obd_ioobj *o = obj;
+        struct niobuf *b = nb;
+        struct niobuf *r = res;
+        int i;
         ENTRY;
 
         memset(res, 0, sizeof(*res) * niocount);
 
-        for (i=0; i < objcount; i++) { 
-                o = obj;
-                obj++; 
-                for (j = 0 ; j < o->ioo_bufcnt ; j++) { 
-                        b = nb;
-                        r = res;
-                        nb++;
-                        res++;
-                        
-                        inode = ioobj_to_inode(conn, o); 
-                        if (!inode) { 
-                                EXIT;
-                                /* FIXME: we need to iput all of previous inodes */
-                                return -EINVAL;
-                        }
+        for (i = 0; i < objcount; i++, o++) {
+                int j;
+                for (j = 0; j < o->ioo_bufcnt; j++, b++, r++) {
+                        struct inode *inode = ioobj_to_inode(conn, o);
+                        struct page *page;
+
+                        /* FIXME: we need to iput all inodes on error */
+                        if (!inode)
+                                RETURN(-EINVAL);
 
                         page = lustre_get_page(inode, b->offset >> PAGE_SHIFT);
-                        if (IS_ERR(page)) { 
-                                EXIT; 
-                                return PTR_ERR(page); 
-                        }
+                        if (IS_ERR(page))
+                                RETURN(PTR_ERR(page));
+
                         if (cmd == OBD_BRW_WRITE) {
-                                rc = lustre_prepare_page(0, PAGE_SIZE, page);
-                        }
-                        if (rc) { 
-                                CERROR("i %d j %d objcount %d bufcnt %d , rc %d, offset %Ld\n", i, j, objcount, o->ioo_bufcnt, rc, b->offset);  
+                                int rc = lustre_prepare_page(0, PAGE_SIZE,page);
+                                if (rc)
+                                        CERROR("i %d j %d objcount %d bufcnt %d , rc %d, offset %Ld\n", i, j, objcount, o->ioo_bufcnt, rc, b->offset);
                         }
-                        
-                        r->addr = (__u64)(unsigned long)page_address(page); 
+
+                        r->addr = (__u64)(unsigned long)page_address(page);
                         r->offset = b->offset;
                         r->page = page;
                         r->len = PAGE_SIZE;
-                        /* r->flags */
                 }
         }
         return 0;
 }
 
-int filter_commitrw(int cmd, struct obd_conn *conn, 
-                     int objcount, struct obd_ioobj *obj, 
-                     int niocount, struct niobuf *res)
+static int filter_commitrw(int cmd, struct obd_conn *conn,
+                           int objcount, struct obd_ioobj *obj,
+                           int niocount, struct niobuf *res)
 {
-        int i, j; 
-        int rc;
-        struct inode *inode;
-        struct obd_ioobj *o;
-        struct niobuf *r = NULL;
+        struct obd_ioobj *o = obj;
+        struct niobuf *r = res;
+        int i;
         ENTRY;
 
-        for (i=0; i < objcount; i++) { 
-                o = obj;
-                obj++; 
+        for (i = 0; i < objcount; i++, obj++) {
+                int j;
+                for (j = 0 ; j < o->ioo_bufcnt ; j++, r++) {
+                        struct page *page = r->page;
 
-                for (j = 0 ; j < o->ioo_bufcnt ; j++) { 
-                        r = res;
-                        if (!r)
+                        if (!r->page)
                                 LBUG();
-                        res++;
 
-                        if (!r) 
-                                LBUG();
+                        if (cmd == OBD_BRW_WRITE) {
+                                int rc = lustre_commit_page(page, 0, PAGE_SIZE);
 
-                        if (cmd == OBD_BRW_WRITE)
-                                rc = lustre_commit_page(r->page, 0, PAGE_SIZE);
-                        else { 
-                                lustre_put_page(r->page);
-                                rc = 0;
-                        }
+                                /* FIXME: still need to iput the other inodes */
+                                if (rc)
+                                        RETURN(rc);
+                        } else
+                                lustre_put_page(page);
 
-                        if (rc) { 
-                                EXIT; 
-                                return rc;
-                        }
-                        inode = ((struct page *)r->page)->mapping->host;
-                        iput(inode); 
+                        iput(page->mapping->host);
                 }
         }
-        return 0;
+        RETURN(0);
 }
 
 static int filter_statfs (struct obd_conn *conn, struct statfs * statfs)
@@ -843,7 +858,7 @@ static int filter_statfs (struct obd_conn *conn, struct statfs * statfs)
         err = sb->s_op->statfs(sb, statfs);
         EXIT;
         return err;
-} /* ext2obd_statfs */
+} /* filter_statfs */
 
 
 static int  filter_get_info(struct obd_conn *conn, obd_count keylen,
@@ -901,6 +916,8 @@ struct obd_ops filter_obd_ops = {
         o_create:      filter_create,
         o_setattr:     filter_setattr,
         o_destroy:     filter_destroy,
+        o_open:        filter_open,
+        o_close:       filter_close,
         o_read:        filter_read,
         o_write:       filter_write,
         o_brw:         filter_pgcache_brw,
@@ -908,10 +925,10 @@ struct obd_ops filter_obd_ops = {
         o_preprw:      filter_preprw,
         o_commitrw:    filter_commitrw
 #if 0
-        o_preallocate: ext2obd_preallocate_inodes,
-        o_migrate:     ext2obd_migrate,
+        o_preallocate: filter_preallocate_inodes,
+        o_migrate:     filter_migrate,
         o_copy:        gen_copy_data,
-        o_iterate:     ext2obd_iterate
+        o_iterate:     filter_iterate
 #endif
 };