Whamcloud - gitweb
- fixes to filter obd
authorbraam <braam>
Sun, 31 Mar 2002 04:31:55 +0000 (04:31 +0000)
committerbraam <braam>
Sun, 31 Mar 2002 04:31:55 +0000 (04:31 +0000)
- move inode size update to file close time.

lustre/llite/file.c
lustre/llite/rw.c
lustre/obdecho/echo.c
lustre/obdfilter/filter.c
lustre/utils/obdctl.c

index d798bce..12f6f08 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/obd_support.h>
 #include <linux/lustre_light.h>
 
+int ll_inode_setattr(struct inode *inode, struct iattr *attr, int do_trunc);
 extern int ll_setattr(struct dentry *de, struct iattr *attr);
 extern inline struct obdo * ll_oa_from_inode(struct inode *inode, int valid);
 
@@ -104,6 +105,8 @@ static int ll_file_release(struct inode *inode, struct file *file)
         struct ll_file_data *fd;
         struct obdo *oa;
         struct ll_sb_info *sbi = ll_i2sbi(inode);
+        struct iattr iattr;
+
         ENTRY;
 
         fd = (struct ll_file_data *)file->private_data;
@@ -125,6 +128,14 @@ static int ll_file_release(struct inode *inode, struct file *file)
                 goto out;
         }
 
+        iattr.ia_valid = ATTR_SIZE;
+        iattr.ia_size = inode->i_size;
+        rc = ll_inode_setattr(inode, &iattr, 0);
+        if (rc) {
+                CERROR("failed - %d.\n", rc);
+                rc = -EIO;
+        }
+
         rc = mdc_close(&sbi->ll_mds_client, inode->i_ino, S_IFREG, 
                       fd->fd_mdshandle, &req); 
         ptlrpc_free_req(req);
index b72ea76..9fedc5d 100644 (file)
@@ -33,7 +33,6 @@
 #include <linux/lustre_mds.h>
 #include <linux/lustre_light.h>
 
-int ll_inode_setattr(struct inode *inode, struct iattr *attr, int do_trunc);
 
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,10))
 /*
@@ -325,11 +324,14 @@ static int ll_commit_write(struct file *file, struct page *page,
                 iattr.ia_valid = ATTR_SIZE;
                 iattr.ia_size = offset + to;
                 /* do NOT truncate */
+                inode->i_size = offset + to;
+#if 0
                 err = ll_inode_setattr(inode, &iattr, 0);
                 if (err) {
                         CERROR("failed - %d.\n", err);
                         err = -EIO;
                 }
+#endif
         }
 
         obdo_free(oa);
index 72e9284..b5fa3a1 100644 (file)
@@ -33,7 +33,7 @@ static struct obdo OA;
 static obd_count GEN;
 static long echo_pages = 0;
 
-int echo_connect (struct obd_conn *conn)
+static int echo_connect(struct obd_conn *conn)
 {
         int rc;
 
@@ -46,7 +46,7 @@ int echo_connect (struct obd_conn *conn)
         return rc;
 }
 
-int echo_disconnect(struct obd_conn *conn)
+static int echo_disconnect(struct obd_conn *conn)
 {
         int rc;
 
index 34c8976..cf81955 100644 (file)
@@ -32,7 +32,6 @@ long filter_memory;
 #define FILTER_ROOTINO 2
 
 #define S_SHIFT 12
-
 static char * obd_type_by_mode[S_IFMT >> S_SHIFT] = {
         [0]                     "",
         [S_IFREG >> S_SHIFT]    "R", 
@@ -44,22 +43,9 @@ static char * obd_type_by_mode[S_IFMT >> S_SHIFT] = {
         [S_IFLNK >> S_SHIFT]    "L"
 };
 
-static void filter_id(char *buf, obd_id id, obd_mode mode)
-{
-        sprintf(buf, "O/%s/%Ld", obd_type_by_mode[(mode & S_IFMT) >> S_SHIFT],
-                id);
-}
-
-static struct file *filter_parent(obd_id id, obd_mode mode)
-{
-        char path[64];
-        struct file *file;
-        sprintf(path, "O/%s", obd_type_by_mode[(mode & S_IFMT) >> S_SHIFT]);
 
-        file = filp_open(path, O_RDONLY, 0); 
-        return file;
-}
 
+/* push / pop to root of obd store */
 void push_ctxt(struct obd_run_ctxt *save, struct obd_run_ctxt *new)
 { 
         save->fs = get_fs();
@@ -79,6 +65,7 @@ void pop_ctxt(struct obd_run_ctxt *saved)
         mntput(saved->pwdmnt);
 }
 
+/* utility to make a directory */
 static int simple_mkdir(struct dentry *dir, char *name, int mode)
 {
         struct dentry *dchild; 
@@ -104,31 +91,14 @@ static int simple_mkdir(struct dentry *dir, char *name, int mode)
         return err;
 }
 
-static int simple_unlink(struct dentry *dir, char *name)
+/* write the pathname into the string */
+static void filter_id(char *buf, obd_id id, obd_mode mode)
 {
-        struct dentry *dchild; 
-        int err;
-        ENTRY;
-        
-        dchild = lookup_one_len(name, dir, strlen(name));
-        if (IS_ERR(dchild)) { 
-                EXIT;
-                return PTR_ERR(dchild); 
-        }
-
-        if (!dchild->d_inode) { 
-                dput(dchild);
-                EXIT;
-                return -ENOENT;
-        }
-
-        err = vfs_unlink(dir->d_inode, dchild);
-        dput(dchild);
-        
-        EXIT;
-        return err;
+        sprintf(buf, "O/%s/%Ld", obd_type_by_mode[(mode & S_IFMT) >> S_SHIFT],
+                id);
 }
 
+/* setup the object store with correct subdirectories */
 static void filter_prep(struct obd_device *obddev)
 {
         struct obd_run_ctxt saved;
@@ -200,6 +170,7 @@ static void filter_prep(struct obd_device *obddev)
         pop_ctxt(&saved);
 }
 
+/* cleanup the filter: write last used object id to status file */
 static void filter_post(struct obd_device *obddev)
 {
         struct obd_run_ctxt saved;
@@ -228,12 +199,108 @@ static void filter_post(struct obd_device *obddev)
 }
 
 
-/* release per client resources */
+static __u64 filter_next_id(struct obd_device *obddev) 
+{
+        __u64 id;
+        spin_lock(&obddev->u.filter.fo_lock);
+        obddev->u.filter.fo_lastino++;
+        id =    obddev->u.filter.fo_lastino;
+        spin_unlock(&obddev->u.filter.fo_lock);
+        return id;
+}
+
+/* how to get files, dentries, inodes from object id's */
+static struct file *filter_obj_open(struct obd_device *obddev, 
+                                   __u64 id, __u32 type)
+{
+        struct obd_run_ctxt saved;
+        char name[24];
+        struct super_block *sb;
+        struct file *file;
+        
+        sb = obddev->u.filter.fo_sb;
+        if (!sb || !sb->s_dev) {
+                CDEBUG(D_SUPER, "fatal: device not initialized.\n");
+                EXIT;
+                return NULL;
+        }
+
+        if ( !id ) {
+                CDEBUG(D_INODE, "fatal: invalid obdo %Lu\n", id);
+                EXIT;
+                return NULL;
+        }
+
+        if ( ! (type & S_IFMT) ) { 
+                CERROR("OBD filter_obj_open, no type (%Ld), mode %o!\n", 
+                       id, type);
+        }
+
+        filter_id(name, id, type); 
+        push_ctxt(&saved, &obddev->u.filter.fo_ctxt);
+        file = filp_open(name, O_RDONLY | O_LARGEFILE, 0);
+        pop_ctxt(&saved);
+
+        CDEBUG(D_INODE, "opening obdo %s\n", name);
+
+        return file;
+}
+
+static struct file *filter_parent(obd_id id, obd_mode mode)
+{
+        char path[64];
+        struct file *file;
+
+        sprintf(path, "O/%s", obd_type_by_mode[(mode & S_IFMT) >> S_SHIFT]);
+
+        file = filp_open(path, O_RDONLY, 0); 
+        return file;
+}
+
+
+static struct inode *filter_inode_from_obj(struct obd_device *obddev, 
+                                     __u64 id, __u32 type)
+{
+        struct file *file;
+        struct inode *inode; 
+
+        file = filter_obj_open(obddev, id, type);
+        if ( !file ) { 
+                CERROR("filter_inode_from_obdo failed\n"); 
+                return NULL;
+        }
+
+        inode = iget(file->f_dentry->d_inode->i_sb, 
+                     file->f_dentry->d_inode->i_ino); 
+        filp_close(file, 0);
+        return inode;
+}
+
+/* obd methods */
+static int filter_connect(struct obd_conn *conn)
+{
+        int rc;
+
+        MOD_INC_USE_COUNT;
+        rc = gen_connect(conn);
+
+        if (rc)
+                MOD_DEC_USE_COUNT;
+
+        return rc;
+}
+
 static int filter_disconnect(struct obd_conn *conn)
 {
+        int rc;
+
+        rc = gen_disconnect(conn);
+        if (!rc)
+                MOD_DEC_USE_COUNT;
+
         /* XXX cleanup preallocated inodes */
-        return gen_disconnect(conn);
-} /* ext2obd_disconnect */
+        return rc;
+}
 
 /* mount the file system (secretly) */
 static int filter_setup(struct obd_device *obddev, obd_count len,
@@ -275,15 +342,6 @@ static int filter_setup(struct obd_device *obddev, obd_count len,
         return 0;
 } 
 
-static __u64 filter_next_id(struct obd_device *obddev) 
-{
-        __u64 id;
-        spin_lock(&obddev->u.filter.fo_lock);
-        obddev->u.filter.fo_lastino++;
-        id =    obddev->u.filter.fo_lastino;
-        spin_unlock(&obddev->u.filter.fo_lock);
-        return id;
-}
 
 static int filter_cleanup(struct obd_device * obddev)
 {
@@ -321,62 +379,6 @@ static int filter_cleanup(struct obd_device * obddev)
         return 0;
 }
 
-static struct file *filter_obj_open(struct obd_device *obddev, 
-                                     struct obdo *oa)
-{
-        struct file *file;
-        int error = 0;
-        char id[24];
-        struct obd_run_ctxt saved;
-        struct super_block *sb;
-
-        sb = obddev->u.filter.fo_sb;
-        if (!sb || !sb->s_dev) {
-                CDEBUG(D_SUPER, "fatal: device not initialized.\n");
-                EXIT;
-                return NULL;
-        }
-
-        if ( !oa->o_id ) {
-                CDEBUG(D_INODE, "fatal: invalid obdo %lu\n", (long)oa->o_id);
-                EXIT;
-                return NULL;
-        }
-
-        if ( ! (oa->o_mode & S_IFMT) ) { 
-                CERROR("OBD filter_obj_open, no type (%Ld), mode %o!\n", 
-                       oa->o_id, oa->o_mode);
-        }
-        filter_id(id, oa->o_id, oa->o_mode); 
-        push_ctxt(&saved, &obddev->u.filter.fo_ctxt);
-        file = filp_open(id , O_RDONLY | O_LARGEFILE, 0);
-        pop_ctxt(&saved);
-
-        if (IS_ERR(file)) { 
-                error = PTR_ERR(file);
-                file = NULL;
-        }
-        CDEBUG(D_INODE, "opening obdo %s\n", id);
-
-        return file;
-}
-
-static struct inode *filter_inode_from_obdo(struct obd_device *obddev, 
-                                     struct obdo *oa)
-{
-        struct file *file;
-        struct inode *inode; 
-
-        file = filter_obj_open(obddev, oa);
-        if ( !file ) { 
-                CERROR("filter_inode_from_obdo failed\n"); 
-                return NULL;
-        }
-
-        inode = iget(file->f_dentry->d_inode->i_sb, file->f_dentry->d_inode->i_ino); 
-        filp_close(file, 0);
-        return inode;
-}
 
 static inline void filter_from_inode(struct obdo *oa, struct inode *inode)
 {
@@ -430,7 +432,8 @@ static int filter_getattr(struct obd_conn *conn, struct obdo *oa)
                 return -EINVAL;
         }
 
-        if ( !(inode = filter_inode_from_obdo(conn->oc_dev, oa)) ) { 
+        if ( !(inode = filter_inode_from_obj(conn->oc_dev, 
+                                              oa->o_id, oa->o_mode)) ) { 
                 EXIT;
                 return -ENOENT;
         }
@@ -455,7 +458,7 @@ static int filter_setattr(struct obd_conn *conn, struct obdo *oa)
                 return -EINVAL;
         }
 
-        inode = filter_inode_from_obdo(conn->oc_dev, oa); 
+        inode = filter_inode_from_obj(conn->oc_dev, oa->o_id, oa->o_mode); 
         if ( !inode ) { 
                 EXIT;
                 return -ENOENT;
@@ -487,10 +490,9 @@ static int filter_create (struct obd_conn* conn, struct obdo *oa)
         ENTRY;
 
         if (!gen_client(conn)) {
-                CDEBUG(D_IOCTL, "invalid client %u\n", conn->oc_id);
+                CERROR("invalid client %u\n", conn->oc_id);
                 return -EINVAL;
         }
-        CDEBUG(D_IOCTL, "\n");
 
         oa->o_id = filter_next_id(conn->oc_dev);
         if ( !(oa->o_mode && S_IFMT) ) { 
@@ -510,7 +512,6 @@ static int filter_create (struct obd_conn* conn, struct obdo *oa)
                 return -ENOENT;
         }
         filp_close(file, 0);
-        CDEBUG(D_IOCTL, "\n");
         
         /* Set flags for fields we have set in ext2_new_inode */
         oa->o_valid |= OBD_MD_FLID | OBD_MD_FLBLKSZ | OBD_MD_FLBLOCKS |
@@ -525,29 +526,27 @@ static int filter_destroy(struct obd_conn *conn, struct obdo *oa)
         struct obd_client * cli;
         struct inode * inode;
         struct file *dir;
+        struct file *object;
         int rc;
         struct obd_run_ctxt saved;
-        char id[128];
 
         if (!(cli = gen_client(conn))) {
-                CDEBUG(D_IOCTL, "invalid client %u\n", conn->oc_id);
+                CERROR("invalid client %u\n", conn->oc_id);
                 EXIT;
                 return -EINVAL;
         }
 
         obddev = conn->oc_dev;
-        inode = filter_inode_from_obdo(obddev, oa);
-
-        if (!inode) { 
+        object = filter_obj_open(obddev, oa->o_id, oa->o_mode);
+        if (!object || IS_ERR(object)) { 
                 EXIT;
                 return -ENOENT;
         }
-
+        
+        inode = object->f_dentry->d_inode;
         inode->i_nlink = 1;
         inode->i_mode = 010000;
-        iput(inode);
 
-        filter_id(id, oa->o_id, oa->o_mode);
         push_ctxt(&saved, &obddev->u.filter.fo_ctxt);
         dir = filter_parent(oa->o_id, oa->o_mode);
         if (IS_ERR(dir)) {
@@ -555,10 +554,12 @@ static int filter_destroy(struct obd_conn *conn, struct obdo *oa)
                 EXIT;
                 goto out;
         }
-
-        rc = simple_unlink(dir->f_dentry, id);
+        dget(dir->f_dentry); 
+        dget(object->f_dentry);
+        rc = vfs_unlink(dir->f_dentry->d_inode, object->f_dentry);
 
         filp_close(dir, 0);
+        filp_close(object, 0);
 out:
         pop_ctxt(&saved);
         EXIT;
@@ -591,7 +592,7 @@ static int filter_read(struct obd_conn *conn, struct obdo *oa, char *buf,
                 return -EINVAL;
         }
 
-        file = filter_obj_open(conn->oc_dev, oa); 
+        file = filter_obj_open(conn->oc_dev, oa->o_id, oa->o_mode); 
         if (!file || IS_ERR(file)) { 
                 EXIT;
                 return -PTR_ERR(file);
@@ -610,7 +611,7 @@ static int filter_read(struct obd_conn *conn, struct obdo *oa, char *buf,
         }
 
         return err;
-} /* ext2obd_read */
+}
 
 
 /* buffer must lie in user memory here */
@@ -628,7 +629,7 @@ static int filter_write(struct obd_conn *conn, struct obdo *oa, char *buf,
                 return -EINVAL;
         }
 
-        file = filter_obj_open(conn->oc_dev, oa); 
+        file = filter_obj_open(conn->oc_dev, oa->o_id, oa->o_mode); 
         if (!file || IS_ERR(file)) { 
                 EXIT;
                 return -PTR_ERR(file);
@@ -684,7 +685,8 @@ static int filter_pgcache_brw(int rw, struct obd_conn *conn,
         for (onum = 0; onum < num_oa; onum++) {
                 int              pg;
 
-                file = filter_obj_open(conn->oc_dev, oa[onum]); 
+                file = filter_obj_open(conn->oc_dev, oa[onum]->o_id, 
+                                       oa[onum]->o_mode); 
                 if (!file || IS_ERR(file)) { 
                         EXIT;
                         error = -ENOENT;
@@ -739,6 +741,134 @@ static int filter_pgcache_brw(int rw, struct obd_conn *conn,
         return error;
 }
 
+
+struct inode *ioobj_to_inode(struct obd_conn *conn, struct obd_ioobj *o)
+{
+        struct inode *inode = NULL;
+        struct super_block *sb = conn->oc_dev->u.ext2.e2_sb;
+
+        if (!sb || !sb->s_dev) {
+                CDEBUG(D_SUPER, "fatal: device not initialized.\n");
+                EXIT;
+                return NULL;
+        }
+
+        if ( !o->ioo_id ) {
+                CDEBUG(D_INODE, "fatal: invalid obdo %lu\n", (long)o->ioo_id);
+                EXIT;
+                return NULL;
+        }
+
+        inode = filter_inode_from_obj(conn->oc_dev, o->ioo_id, S_IFREG);
+        if (!inode || inode->i_nlink == 0 || is_bad_inode(inode)) {
+                CERROR("from obdo - fatal: invalid inode %ld (%s).\n",
+                       (long)o->ioo_id, inode ? inode->i_nlink ? "bad inode" :
+                       "no links" : "NULL");
+                if (inode)
+                        iput(inode);
+                EXIT;
+                return NULL;
+        }
+
+        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)
+{
+        int i, j; 
+        struct obd_ioobj *o;
+        struct niobuf *b;
+        struct niobuf *r;
+        struct inode *inode;
+        struct page *page;
+        int rc = 0;
+        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;
+                        }
+
+                        page = lustre_get_page(inode, b->offset >> PAGE_SHIFT);
+                        if (IS_ERR(page)) { 
+                                EXIT; 
+                                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);  
+                        }
+                        
+                        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)
+{
+        int i, j; 
+        int rc;
+        struct inode *inode;
+        struct obd_ioobj *o;
+        struct niobuf *r = NULL;
+        ENTRY;
+
+        for (i=0; i < objcount; i++) { 
+                o = obj;
+                obj++; 
+
+                for (j = 0 ; j < o->ioo_bufcnt ; j++) { 
+                        r = res;
+                        if (!r)
+                                LBUG();
+                        res++;
+
+                        if (!r) 
+                                LBUG();
+
+                        if (cmd == OBD_BRW_WRITE)
+                                rc = lustre_commit_page(r->page, 0, PAGE_SIZE);
+                        else { 
+                                lustre_put_page(r->page);
+                                rc = 0;
+                        }
+
+                        if (rc) { 
+                                EXIT; 
+                                return rc;
+                        }
+                        inode = ((struct page *)r->page)->mapping->host;
+                        iput(inode); 
+                }
+        }
+        return 0;
+}
+
 static int filter_statfs (struct obd_conn *conn, struct statfs * statfs)
 {
         struct super_block *sb;
@@ -808,7 +938,7 @@ struct obd_ops filter_obd_ops = {
         o_get_info:    filter_get_info,
         o_setup:       filter_setup,
         o_cleanup:     filter_cleanup,
-        o_connect:     gen_connect,
+        o_connect:     filter_connect,
         o_disconnect:  filter_disconnect,
         o_statfs:      filter_statfs,
         o_getattr:     filter_getattr,
@@ -819,6 +949,8 @@ struct obd_ops filter_obd_ops = {
         o_write:       filter_write,
         o_brw:         filter_pgcache_brw,
         o_punch:       filter_truncate,
+        o_preprw:      filter_preprw,
+        o_commitrw:    filter_commitrw
 #if 0
         o_preallocate: ext2obd_preallocate_inodes,
         o_migrate:     ext2obd_migrate,
index e71bfd0..933ebf6 100644 (file)
@@ -402,7 +402,7 @@ static int jt_setattr(int argc, char **argv)
         }
 
         data.ioc_obdo1.o_id = strtoul(argv[1], NULL, 0);
-        data.ioc_obdo1.o_mode = strtoul(argv[2], NULL, 0);
+        data.ioc_obdo1.o_mode = S_IFREG | strtoul(argv[2], NULL, 0);
         data.ioc_obdo1.o_valid = OBD_MD_FLMODE; 
 
         rc = ioctl(fd, OBD_IOC_SETATTR , &data);
@@ -423,6 +423,7 @@ static int jt_destroy(int argc, char **argv)
         }
 
         data.ioc_obdo1.o_id = strtoul(argv[1], NULL, 0);
+        data.ioc_obdo1.o_mode = S_IFREG|0644;
 
         rc = ioctl(fd, OBD_IOC_DESTROY , &data);
         if (rc < 0) {
@@ -439,6 +440,8 @@ static int jt_getattr(int argc, char **argv)
         IOCINIT(data);
         if (argc == 2) {
                 data.ioc_obdo1.o_id = strtoul(argv[1], NULL, 0);
+                /* to help obd filter */ 
+                data.ioc_obdo1.o_mode = 0100644;
                 data.ioc_obdo1.o_valid = 0xffffffff;
                 printf("getting attr for %Ld\n", data.ioc_obdo1.o_id);
         } else {