Whamcloud - gitweb
assorted bug fixes and a working directory readpage routine
authorbraam <braam>
Mon, 21 Jan 2002 23:58:26 +0000 (23:58 +0000)
committerbraam <braam>
Mon, 21 Jan 2002 23:58:26 +0000 (23:58 +0000)
 for Lustre Light.

15 files changed:
lustre/include/linux/lustre_idl.h
lustre/include/linux/lustre_light.h
lustre/include/linux/lustre_mds.h
lustre/include/linux/obdo.h
lustre/lib/mds_pack.c
lustre/llite/dir.c
lustre/llite/namei.c
lustre/llite/rw.c
lustre/llite/super.c
lustre/mdc/mdc_request.c
lustre/mds/handler.c
lustre/obdfs/super.c
lustre/tests/llmount.sh
lustre/tests/mdcreq.sh
lustre/tests/testreq.c

index 4713905..5b9b033 100644 (file)
@@ -193,6 +193,18 @@ struct obd_bufref {
 #define MDS_TYPE_REP 2
 #define MDS_TYPE_ERR 3
 
+#define MDS_GETATTR   1
+#define MDS_SETATTR   2
+#define MDS_READPAGE  3
+#define MDS_CREATE    4
+#define MDS_LINK      5
+#define MDS_SYMLINK   6
+#define MDS_MKNOD     7
+#define MDS_MKDIR     8
+#define MDS_UNLINK    9
+#define MDS_RMDIR    10
+#define MDS_RENAME   11
+
 struct mds_req_hdr { 
        __u32 opc;
        __u64 seqno;
@@ -206,6 +218,9 @@ struct lustre_fid {
        __u32 f_type;
 };
 
+struct niobuf { 
+        __u64 addr;
+};
 
 struct mds_rep_hdr { 
        __u32 opc;
index 1fea41d..77244d2 100644 (file)
@@ -28,8 +28,8 @@ struct ll_sb_info {
         struct list_head         ll_list;      /* list of supers */
         struct obd_conn          ll_conn;
         struct super_block      *ll_super;
-        struct obd_device       *ll_obd;
-        struct obd_ops          *ll_ops;
+       //        struct obd_device       *ll_obd;
+        //struct obd_ops          *ll_ops;
         ino_t                    ll_rootino;   /* number of root inode */
         int                      ll_minor;     /* minor of /dev/obdX */
         struct list_head         ll_inodes;    /* list of dirty inodes */
index c018d75..4891588 100644 (file)
@@ -57,17 +57,6 @@ struct mds_obd {
        struct address_space_operations *mds_aops;
 };
 
-#define MDS_GETATTR   1
-#define MDS_SETATTR  2
-#define MDS_OPEN     3
-#define MDS_CREATE   4
-#define MDS_LINK     5
-#define MDS_SYMLINK  6
-#define MDS_MKNOD    7
-#define MDS_MKDIR    8
-#define MDS_UNLINK   9
-#define MDS_RMDIR   10
-#define MDS_RENAME  11
 
 struct mds_request { 
        struct list_head rq_list;
@@ -110,7 +99,7 @@ struct mds_req {
         __u32                       nlink;
         __u32                       generation;
         char                      *name;
-        char                      *tgt;
+        char                       *tgt;
 };
 
 /* more or less identical to the packed structure, except for the pointers */
@@ -134,7 +123,7 @@ struct mds_rep {
         __u32                       nlink;
         __u32                       generation;
         char                      *name;
-        char                      *tgt;
+        char                       *tgt;
 };
 
 
@@ -148,6 +137,8 @@ int mds_unpack_rep(char *buf, int len, struct mds_rep_hdr **hdr, struct mds_rep
 /* llight/request.c */
 int mdc_getattr(ino_t ino, int type, int valid, 
                struct mds_rep  **mds_reply, struct mds_rep_hdr **hdr);
+int mdc_readpage(ino_t ino, int type, __u64 offset, char *addr, 
+                 struct mds_rep  **rep, struct mds_rep_hdr **hdr);
 
 
 
@@ -156,7 +147,8 @@ int mdc_getattr(ino_t ino, int type, int valid,
 #define IOC_REQUEST_MIN_NR                 30
 
 #define IOC_REQUEST_GETATTR            _IOWR('f', 30, long)
-#define IOC_REQUEST_MAX_NR               30
+#define IOC_REQUEST_READPAGE           _IOWR('f', 31, long)
+#define IOC_REQUEST_MAX_NR               31
 
 #endif
 
index a111fd5..4255482 100644 (file)
@@ -19,7 +19,6 @@ struct obdfs_sb_info {
         struct obd_conn          osi_conn;
         struct super_block      *osi_super;
         struct obd_device       *osi_obd;
-        struct obd_ops          *osi_ops;
         ino_t                    osi_rootino;   /* number of root inode */
         int                      osi_minor;     /* minor of /dev/obdX */
         struct list_head         osi_inodes;    /* list of dirty inodes */
index 86d78e0..f13eaa4 100644 (file)
@@ -83,7 +83,7 @@ int mds_pack_req(char *name, int namelen, char *tgt, int tgtlen,
        } 
 
        (*req)->tgtlen = NTOH__u32(tgtlen);
-       if (tgt) { 
+       if (tgt) {
                 preq->tgt_offset = (__u32)(ptr - (char *)preq);
                LOGL(tgt, tgtlen, ptr);
        }
@@ -110,7 +110,7 @@ int mds_unpack_req(char *buf, int len,
 
         *req = (struct mds_req *) (buf + sizeof(**hdr));
        (*req)->namelen = NTOH__u32((*req)->namelen); 
-       (*req)->tgtlen = NTOH__u32((*req)->namelen); 
+       (*req)->tgtlen = NTOH__u32((*req)->tgtlen); 
 
        if (len < sizeof(**hdr) + sizeof(**req) + (*req)->namelen + 
            (*req)->tgtlen ) { 
index 12be7a2..f07a310 100644 (file)
@@ -32,6 +32,9 @@ typedef struct ext2_dir_entry_2 ext2_dirent;
 #define PageChecked(page)        test_bit(PG_checked, &(page)->flags)
 #define SetPageChecked(page)     set_bit(PG_checked, &(page)->flags)
 
+
+
+
 int waitfor_one_page(struct page *page)
 {
        int error = 0;
index 9dc1050..15bd677 100644 (file)
@@ -82,8 +82,10 @@ static inline int ext2_add_nondir(struct dentry *dentry, struct inode *inode)
 /* methods */
 static struct dentry *ll_lookup(struct inode * dir, struct dentry *dentry)
 {
-        struct obdo *oa;
+       struct mds_rep *rep; 
+       struct mds_rep_hdr *hdr = NULL; 
        struct inode * inode = NULL;
+       int err;
        int type;
        ino_t ino;
        
@@ -95,16 +97,16 @@ static struct dentry *ll_lookup(struct inode * dir, struct dentry *dentry)
        if (!ino)
                goto negative;
 
-        oa = obdo_fromid(IID(dir), ino, type
-                        OBD_MD_FLNOTOBD | OBD_MD_FLBLOCKS);
-        if ( IS_ERR(oa) ) {
+       err = mdc_getattr(ino, type, OBD_MD_FLNOTOBD|OBD_MD_FLBLOCKS
+                        &rep, &hdr);
+        if ( err ) {
                 printk(__FUNCTION__ ": obdo_fromid failed\n");
                 EXIT;
                 return ERR_PTR(-EACCES); 
         }
 
-       inode = iget4(dir->i_sb, ino, NULL, oa);
-        obdo_free(oa);
+       inode = iget4(dir->i_sb, ino, NULL, rep);
+       kfree(hdr); 
 
        if (!inode) 
                return ERR_PTR(-EACCES);
@@ -138,11 +140,7 @@ static struct inode *ll_new_inode(struct inode *dir, int mode)
         int err;
 
         ENTRY;
-        if (IOPS(dir, create) == NULL) {
-                printk(KERN_ERR __FUNCTION__ ": no create method!\n");
-                EXIT;
-                return ERR_PTR(-EIO);
-        }
+
         oa = obdo_alloc();
         if (!oa) {
                 EXIT;
@@ -153,7 +151,7 @@ static struct inode *ll_new_inode(struct inode *dir, int mode)
         oa->o_mode = mode;
         oa->o_valid |= OBD_MD_FLMODE;
        CDEBUG(D_INODE, "\n");
-        err = IOPS(dir, create)(IID(dir), oa);
+        err = obd_create(IID(dir), oa);
        CDEBUG(D_INODE, "\n");
 
         if ( err ) {
@@ -170,7 +168,7 @@ static struct inode *ll_new_inode(struct inode *dir, int mode)
 
         if (!inode) {
                 printk("new_inode -fatal:  %ld\n", (long)oa->o_id);
-                IOPS(dir, destroy)(IID(dir), oa);
+                obd_destroy(IID(dir), oa);
                 EXIT;
                 return ERR_PTR(-EIO);
         }
@@ -180,7 +178,7 @@ static struct inode *ll_new_inode(struct inode *dir, int mode)
                       (long)oa->o_id,
                       atomic_read(&inode->i_count), 
                       inode->i_nlink);
-                IOPS(dir, destroy)(IID(dir), oa);
+                obd_destroy(IID(dir), oa);
                 iput(inode);
                 EXIT;
                 return ERR_PTR(-EIO);
index a20f267..46eaee8 100644 (file)
@@ -33,6 +33,9 @@
 #include <linux/smp_lock.h>
 
 #include <linux/obd_support.h>
+#include <linux/lustre_lib.h>
+#include <linux/lustre_idl.h>
+#include <linux/lustre_mds.h>
 #include <linux/lustre_light.h>
 
 void ll_change_inode(struct inode *inode);
@@ -107,11 +110,6 @@ static int ll_brw(int rw, struct inode *inode, struct page *page, int create)
         int              err;
 
         ENTRY;
-        if (IOPS(inode, brw) == NULL) {
-                printk(KERN_ERR __FUNCTION__ ": no brw method!\n");
-                EXIT;
-                return -EIO;
-        }
 
         oa = obdo_alloc();
         if ( !oa ) {
@@ -121,7 +119,7 @@ static int ll_brw(int rw, struct inode *inode, struct page *page, int create)
        oa->o_valid = OBD_MD_FLNOTOBD;
         ll_from_inode(oa, inode);
 
-        err = IOPS(inode, brw)(rw, IID(inode), num_obdo, &oa, &bufs_per_obdo,
+        err = obd_brw(rw, IID(inode), num_obdo, &oa, &bufs_per_obdo,
                                &page, &count, &offset, &flags);
         //if ( !err )
        //      ll_to_inode(inode, oa); /* copy o_blocks to i_blocks */
@@ -146,12 +144,6 @@ static int ll_commit_page(struct page *page, int create, int from, int to)
         int              err;
 
         ENTRY;
-        if (IOPS(inode, brw) == NULL) {
-                printk(KERN_ERR __FUNCTION__ ": no brw method!\n");
-                EXIT;
-                return -EIO;
-        }
-
         oa = obdo_alloc();
         if ( !oa ) {
                 EXIT;
@@ -163,7 +155,7 @@ static int ll_commit_page(struct page *page, int create, int from, int to)
        CDEBUG(D_INODE, "commit_page writing (at %d) to %d, count %Ld\n", 
               from, to, count);
 
-        err = IOPS(inode, brw)(WRITE, IID(inode), num_obdo, &oa, &bufs_per_obdo,
+        err = obd_brw(WRITE, IID(inode), num_obdo, &oa, &bufs_per_obdo,
                                &page, &count, &offset, &flags);
         if ( !err ) {
                 SetPageUptodate(page);
@@ -213,6 +205,54 @@ int ll_readpage(struct file *file, struct page *page)
         return 0;
 } /* ll_readpage */
 
+
+
+/* returns the page unlocked, but with a reference */
+int ll_dir_readpage(struct file *file, struct page *page)
+{
+       struct inode *inode = page->mapping->host;
+       char *buf;
+       __u64 offset;
+        int rc = 0;
+       struct mds_rep_hdr *hdr;
+
+        ENTRY;
+
+       if ( ((inode->i_size + PAGE_CACHE_SIZE -1)>>PAGE_SHIFT) 
+            <= page->index) {
+               memset(kmap(page), 0, PAGE_CACHE_SIZE);
+               kunmap(page);
+               goto readpage_out;
+       }
+
+       if (Page_Uptodate(page)) {
+               EXIT;
+               goto readpage_out;
+       }
+
+       offset = page->index << PAGE_SHIFT; 
+       buf = kmap(page);
+        rc = mdc_readpage(inode->i_ino, S_IFDIR, offset, buf, NULL, &hdr);
+       kunmap(buff); 
+        if ( rc ) {
+               EXIT; 
+               goto readpage_out;
+        } 
+
+       if ((rc = hdr->status)) {
+               EXIT;
+               goto readpage_out;
+       }
+
+        /* PDEBUG(page, "READ"); */
+
+       SetPageUptodate(page);
+ readpage_out:
+       unlock_page(page);
+        EXIT;
+        return rc;
+} /* ll_dir_readpage */
+
 int ll_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
 {
         struct inode *inode = page->mapping->host;
@@ -348,11 +388,6 @@ int ll_do_vec_wr(struct inode **inodes, obd_count num_io,
         int err;
 
         ENTRY;
-        if (IOPS(inodes[0], brw) == NULL) {
-                printk(KERN_ERR __FUNCTION__ ": no brw method!\n");
-                EXIT;
-                return -EIO;
-        }
 
         CDEBUG(D_INFO, "writing %d page(s), %d obdo(s) in vector\n",
                num_io, num_obdos);
@@ -368,7 +403,7 @@ int ll_do_vec_wr(struct inode **inodes, obd_count num_io,
                 printk("\n");
         }
 
-        err = IOPS(inodes[0], brw)(WRITE, IID(inodes[0]), num_obdos, obdos,
+        err = obd_brw(WRITE, IID(inodes[0]), num_obdos, obdos,
                                   oa_bufs, pages, counts, offsets, flags);
 
         CDEBUG(D_INFO, "BRW done\n");
@@ -673,12 +708,6 @@ void ll_truncate(struct inode *inode)
 
         //ll_dequeue_pages(inode);
 
-        if (IOPS(inode, punch) == NULL) {
-                printk(KERN_ERR __FUNCTION__ ": no punch method!\n");
-                EXIT;
-                return;
-        }
-
         oa = obdo_alloc();
         if ( !oa ) {
                 /* XXX This would give an inconsistent FS, so deal with it as
@@ -691,14 +720,14 @@ void ll_truncate(struct inode *inode)
                 obdo.o_valid = OBD_MD_FLNOTOBD;
                 ll_from_inode(&obdo, inode);
 
-                err = IOPS(inode, punch)(IID(inode), &obdo, 0, obdo.o_size);
+                err = obd_punch(IID(inode), &obdo, 0, obdo.o_size);
         } else {
                 oa->o_valid = OBD_MD_FLNOTOBD;
                 ll_from_inode(oa, inode);
 
                 CDEBUG(D_INFO, "calling punch for %ld (%Lu bytes at 0)\n",
                        (long)oa->o_id, oa->o_size);
-                err = IOPS(inode, punch)(IID(inode), oa, oa->o_size, 0);
+                err = obd_punch(IID(inode), oa, oa->o_size, 0);
 
                 obdo_free(oa);
         }
@@ -719,3 +748,8 @@ struct address_space_operations ll_aops = {
         commit_write: ll_commit_write,
         bmap: NULL
 };
+
+
+struct address_space_operations ll_dir_aops = {
+        readpage: ll_dir_readpage
+};
index d788210..43f3457 100644 (file)
@@ -37,6 +37,7 @@
 
 //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;
@@ -123,8 +124,6 @@ static struct super_block * ll_read_super(struct super_block *sb,
         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"); 
 
@@ -137,16 +136,13 @@ static struct super_block * ll_read_super(struct super_block *sb,
         }
        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);
 
-        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;
@@ -155,25 +151,20 @@ static struct super_block * ll_read_super(struct super_block *sb,
         sb->s_op = &ll_super_operations;
 
         /* make root inode */
-        CDEBUG(D_INFO, "\n"); 
        err = mdc_getattr(root_ino, 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;
                 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");
+            printk("lustre_light: bad iget4 for root\n");
             sb->s_dev = 0;
             err = -ENOENT;
             EXIT;
@@ -181,7 +172,6 @@ static struct super_block * ll_read_super(struct super_block *sb,
         } 
         
         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);
@@ -195,7 +185,7 @@ ERR:
         if (version)
                 OBD_FREE(version, strlen(version) + 1);
        if (connected) 
-               sbi->ll_ops->o_disconnect(&sbi->ll_conn);
+               obd_disconnect(&sbi->ll_conn);
 
         if (sbi) {
                 sbi->ll_super = NULL;
@@ -216,10 +206,7 @@ static void ll_put_super(struct super_block *sb)
         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);
+        obd_disconnect(ID(sb));
         
         printk(KERN_INFO "OBDFS: Bye bye.\n");
 
@@ -227,18 +214,13 @@ static void ll_put_super(struct super_block *sb)
         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");
@@ -249,7 +231,7 @@ void ll_do_change_inode(struct inode *inode, int valid)
         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);
+        err = obd_setattr(IID(inode), oa);
 
         if ( err )
                 printk(__FUNCTION__ ": obd_setattr fails (%d)\n", err);
@@ -364,11 +346,7 @@ int ll_setattr(struct dentry *de, struct iattr *attr)
         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");
@@ -379,7 +357,7 @@ int ll_setattr(struct dentry *de, struct iattr *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);
+        err = obd_setattr(IID(inode), oa);
 
         if ( err )
                 printk(__FUNCTION__ ": obd_setattr fails (%d)\n", err);
@@ -398,7 +376,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;
@@ -430,7 +408,7 @@ 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) { 
@@ -455,12 +433,10 @@ 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,
+        put_super: ll_put_super,
         // statfs: ll_statfs
 };
 
-
-
 struct file_system_type lustre_light_fs_type = {
    "lustre_light", 0, ll_read_super, NULL
 };
index 07ce317..ac1f6ac 100644 (file)
@@ -35,7 +35,7 @@
 
 extern int mds_queue_req(struct mds_request *);
 
-struct mds_request *mds_prep_req(int size, int opcode)
+struct mds_request *mds_prep_req(int size, int opcode, int namelen, char *name, int tgtlen, char *tgt)
 {
        struct mds_request *request;
        int rc;
@@ -47,7 +47,7 @@ struct mds_request *mds_prep_req(int size, int opcode)
                return NULL;
        }
 
-       rc = mds_pack_req(NULL, 0, NULL, 0, 
+       rc = mds_pack_req(name, namelen, tgt, tgtlen,
                          &request->rq_reqhdr, &request->rq_req, 
                          &request->rq_reqlen, &request->rq_reqbuf);
        if (rc) { 
@@ -71,7 +71,7 @@ static int mds_queue_wait(struct mds_request *req)
        /* hand the packet over to the server */
        rc = mds_queue_req(req); 
        if (rc) { 
-               printk("osc_queue_wait: error %d, opcode %d\n", rc, 
+               printk("mdc_queue_wait: error %d, opcode %d\n", rc, 
                       req->rq_reqhdr->opc); 
                return -rc;
        }
@@ -83,7 +83,7 @@ static int mds_queue_wait(struct mds_request *req)
 
        mds_unpack_rep(req->rq_repbuf, req->rq_replen, &req->rq_rephdr, 
                       &req->rq_rep); 
-       printk("-->osc_queue_wait: buf %p len %d status %d\n", 
+       printk("-->mdc_queue_wait: buf %p len %d status %d\n", 
               req->rq_repbuf, req->rq_replen, req->rq_rephdr->status); 
 
        EXIT;
@@ -101,7 +101,8 @@ int mdc_getattr(ino_t ino, int type, int valid,
        struct mds_request *request;
        int rc; 
 
-       request = mds_prep_req(sizeof(*request), MDS_GETATTR); 
+       request = mds_prep_req(sizeof(*request), MDS_GETATTR, 
+                              0, NULL, 0, NULL); 
        if (!request) { 
                printk("llight request: cannot pack\n");
                return -ENOMEM;
@@ -131,6 +132,51 @@ int mdc_getattr(ino_t ino, int type, int valid,
        return rc;
 }
 
+int mdc_readpage(ino_t ino, int type, __u64 offset, char *addr, 
+               struct mds_rep  **rep, struct mds_rep_hdr **hdr)
+{
+       struct mds_request *request;
+       struct niobuf niobuf;
+       int rc; 
+
+       niobuf.addr = (__u64) (long) addr;
+
+       printk("mdc_readpage: inode: %ld\n", ino); 
+
+       request = mds_prep_req(sizeof(*request), MDS_READPAGE, 
+                              0, NULL,
+                              sizeof(struct niobuf), (char *)&niobuf);
+       if (!request) { 
+               printk("mdc request: cannot pack\n");
+               return -ENOMEM;
+       }
+
+       request->rq_req->fid1.id = ino;
+       request->rq_req->fid1.f_type = type;
+       request->rq_req->size = offset;
+       request->rq_req->tgtlen = sizeof(niobuf); 
+
+       rc = mds_queue_wait(request);
+       if (rc) { 
+               printk("mdc request: error in handling %d\n", rc); 
+               goto out;
+       }
+
+       printk("mdc_readpage: mode: %o\n", request->rq_rep->mode); 
+
+       if (rep) { 
+               *rep = request->rq_rep;
+       }
+       if (hdr) { 
+               *hdr = request->rq_rephdr;
+       }
+
+ out: 
+       mds_free_req(request);
+       return rc;
+}
+
+
 static int request_ioctl(struct inode *inode, struct file *file, 
                       unsigned int cmd, unsigned long arg)
 {
@@ -162,6 +208,26 @@ static int request_ioctl(struct inode *inode, struct file *file,
                printk("-- done err %d\n", err);
                break;
        }
+
+       case IOC_REQUEST_READPAGE: { 
+               struct mds_rep_hdr *hdr;
+               char *buf;
+               buf = kmalloc(PAGE_SIZE, GFP_KERNEL); 
+               if (!buf) { 
+                       err = -ENOMEM;
+                       break;
+               }
+               printk("-- readpage 0 for ino 2\n"); 
+               err = mdc_readpage(2, S_IFDIR, 0, buf, NULL, &hdr);
+               printk("-- done err %d\n", err);
+               if (!err) { 
+                       printk("-- status: %d\n", hdr->status); 
+                       err = hdr->status;
+                       kfree(hdr);
+               }
+               kfree(buf); 
+               break;
+       }
        default:                
                err = -EINVAL;
                EXIT;
@@ -201,6 +267,7 @@ MODULE_DESCRIPTION("Lustre MDS Request Tester v1.0");
 MODULE_LICENSE("GPL");
 
 EXPORT_SYMBOL(mdc_getattr); 
+EXPORT_SYMBOL(mdc_readpage); 
 
 module_init(mds_request_init);
 module_exit(mds_request_exit);
index f272a2c..3a29163 100644 (file)
@@ -70,6 +70,20 @@ static int mds_queue_req(struct mds_request *req)
        return 0;
 }
 
+/* XXX do this over the net */
+int mds_sendpage(struct mds_request *req, struct file *file, 
+                   __u64 offset, struct niobuf *dst)
+{
+       int rc; 
+
+       rc = generic_file_read(file, (char *)(long)dst->addr, 
+                             PAGE_SIZE, &offset); 
+
+       if (rc != PAGE_SIZE) 
+               return -EIO;
+       return 0;
+}
+
 /* XXX replace with networking code */
 int mds_reply(struct mds_request *req)
 {
@@ -117,32 +131,78 @@ int mds_error(struct mds_request *req)
        return mds_reply(req);
 }
 
-
-
-static struct dentry *mds_fid2dentry(struct mds_obd *mds, struct lustre_fid *fid)
+static struct dentry *mds_fid2dentry(struct mds_obd *mds, struct lustre_fid *fid, struct vfsmount **mnt)
 {
-       struct dentry *de;
+
+       /* iget isn't really right if the inode is currently unallocated!!
+        * This should really all be done inside each filesystem
+        *
+        * ext2fs' read_inode has been strengthed to return a bad_inode if the inode
+        *   had been deleted.
+        *
+        * Currently we don't know the generation for parent directory, so a generation
+        * of 0 means "accept any"
+        */
+       struct super_block *sb = mds->mds_sb; 
+       unsigned long ino = fid->id;
+       __u32 generation = fid->generation;
        struct inode *inode;
+       struct list_head *lp;
+       struct dentry *result;
 
-       inode = iget(mds->mds_sb, fid->id);
-       if (!inode) { 
-               EXIT;
+       if (mnt) { 
+               *mnt = mntget(mds->mds_vfsmnt);
        }
 
-       de = d_alloc_root(inode);
-       if (!de) { 
+       if (ino == 0)
+               return ERR_PTR(-ESTALE);
+       inode = iget(sb, ino);
+       if (inode == NULL)
+               return ERR_PTR(-ENOMEM);
+
+       printk("--> mds_fid2dentry: sb %p\n", inode->i_sb); 
+
+       if (is_bad_inode(inode)
+           || (generation && inode->i_generation != generation)
+               ) {
+               /* we didn't find the right inode.. */
+               printk("mds_fid2dentry: Inode %lu, Bad count: %d %d or version  %u %u\n",
+                       inode->i_ino,
+                       inode->i_nlink, atomic_read(&inode->i_count),
+                       inode->i_generation,
+                       generation);
+
                iput(inode);
-               EXIT;
-               return NULL;
+               return ERR_PTR(-ESTALE);
        }
-
-       de->d_inode = inode;
-       return de;
+       /* now to find a dentry.
+        * If possible, get a well-connected one
+        */
+       spin_lock(&dcache_lock);
+       for (lp = inode->i_dentry.next; lp != &inode->i_dentry ; lp=lp->next) {
+               result = list_entry(lp,struct dentry, d_alias);
+               if (! (result->d_flags & DCACHE_NFSD_DISCONNECTED)) {
+                       dget_locked(result);
+                       result->d_vfs_flags |= DCACHE_REFERENCED;
+                       spin_unlock(&dcache_lock);
+                       iput(inode);
+                       return result;
+               }
+       }
+       spin_unlock(&dcache_lock);
+       result = d_alloc_root(inode);
+       if (result == NULL) {
+               iput(inode);
+               return ERR_PTR(-ENOMEM);
+       }
+       result->d_flags |= DCACHE_NFSD_DISCONNECTED;
+       return result;
 }
 
 int mds_getattr(struct mds_request *req)
 {
-       struct dentry *de = mds_fid2dentry(req->rq_obd, &req->rq_req->fid1);
+       struct dentry *de = mds_fid2dentry(req->rq_obd, &req->rq_req->fid1, 
+                                          NULL);
        struct inode *inode;
        struct mds_rep *rep;
        int rc;
@@ -166,6 +226,7 @@ int mds_getattr(struct mds_request *req)
        }
 
        inode = de->d_inode;
+       rep->ino = inode->i_ino;
        rep->atime = inode->i_atime;
        rep->ctime = inode->i_ctime;
        rep->mtime = inode->i_mtime;
@@ -179,6 +240,57 @@ int mds_getattr(struct mds_request *req)
        return 0;
 }
 
+int mds_readpage(struct mds_request *req)
+{
+       struct vfsmount *mnt;
+       struct dentry *de = mds_fid2dentry(req->rq_obd, &req->rq_req->fid1, 
+                                          &mnt);
+       struct file *file; 
+       struct niobuf *niobuf; 
+       struct mds_rep *rep;
+       int rc;
+       
+       printk("mds_readpage: ino %ld\n", de->d_inode->i_ino);
+       rc = mds_pack_rep(NULL, 0, NULL, 0, &req->rq_rephdr, &req->rq_rep, 
+                         &req->rq_replen, &req->rq_repbuf);
+       if (rc) { 
+               EXIT;
+               printk("mds: out of memory\n");
+               req->rq_status = -ENOMEM;
+               return -ENOMEM;
+       }
+
+       req->rq_rephdr->seqno = req->rq_reqhdr->seqno;
+       rep = req->rq_rep;
+
+       if (IS_ERR(de)) { 
+               EXIT;
+               req->rq_rephdr->status = PTR_ERR(de); 
+               return 0;
+       }
+
+       file = dentry_open(de, mnt, O_RDONLY | O_LARGEFILE); 
+       /* note: in case of an error, dentry_open puts dentry */
+       if (IS_ERR(file)) { 
+               EXIT;
+               req->rq_rephdr->status = PTR_ERR(file);
+               return 0;
+       }
+               
+       niobuf = (struct niobuf *)req->rq_req->tgt;
+
+       /* to make this asynchronous make sure that the handling function 
+          doesn't send a reply when this function completes. Instead a 
+          callback function would send the reply */ 
+       rc = mds_sendpage(req, file, req->rq_req->size, niobuf); 
+
+       filp_close(file, 0);
+       req->rq_rephdr->status = rc;
+       EXIT;
+       return 0;
+}
+
+
 
 //int mds_handle(struct mds_conn *conn, int len, char *buf)
 int mds_handle(struct mds_request *req)
@@ -212,8 +324,10 @@ int mds_handle(struct mds_request *req)
                rc = mds_getattr(req);
                break;
 
-       case MDS_OPEN:
-               return mds_getattr(req);
+       case MDS_READPAGE:
+               CDEBUG(D_INODE, "readpage\n");
+               rc = mds_readpage(req);
+               break;
 
        case MDS_SETATTR:
                return mds_getattr(req);
index 93a8600..2422881 100644 (file)
@@ -227,7 +227,7 @@ ERR:
         if (version)
                 OBD_FREE(version, strlen(version) + 1);
        if (connected) 
-               sbi->osi_ops->o_disconnect(&sbi->osi_conn);
+               obd_disconnect(&sbi->osi_conn);
 
         if (sbi) {
                 sbi->osi_super = NULL;
index bd3e04c..703e10f 100755 (executable)
@@ -12,11 +12,11 @@ insmod $R/usr/src/obd/mdc/mdc.o
 insmod $R/usr/src/obd/llight/llight.o
 
 dd if=/dev/zero of=/tmp/ost bs=1024 count=10000
-mke2fs -F /tmp/ost
+mke2fs -b 4096 -F /tmp/ost
 losetup /dev/loop/0 /tmp/ost
 
 dd if=/dev/zero of=/tmp/mds bs=1024 count=10000
-mke2fs -F /tmp/mds
+mke2fs -b 4096 -F /tmp/mds
 losetup /dev/loop/1 /tmp/mds
 
 mknod /dev/obd c 10 241
@@ -38,9 +38,7 @@ quit
 EOF
 
 mkdir /mnt/obd
-mount -t lustre_light -o device=3 none /mnt/obd
+mount -t lustre_light -o device=3 none /mnt/obd
 
-mknod /dev/request c 10 244
-# $R/usr/src/obd/utils/testreq
 
 
index 42c623b..4625991 100644 (file)
@@ -13,7 +13,7 @@ insmod $R/usr/src/obd/mdc/mdc.o
 insmod $R/usr/src/obd/llight/llight.o
 
 dd if=/dev/zero of=/tmp/fs bs=1024 count=10000
-mke2fs -F /tmp/fs
+mke2fs -b 4096 -F /tmp/fs
 losetup /dev/loop/0 /tmp/fs
 
 
index b47b31c..98886f4 100644 (file)
@@ -3,8 +3,8 @@
 #include <fcntl.h>
 #include <errno.h>
 #include <string.h>
-
 #define IOC_REQUEST_GETATTR            _IOWR('f', 30, long)
+#define IOC_REQUEST_READPAGE           _IOWR('f', 31, long)
 
 int main(int argc, char **argv)
 {
@@ -20,7 +20,12 @@ int main(int argc, char **argv)
                return 1;
        }
 
+       printf("getattr test... ");
        rc = ioctl(fd, IOC_REQUEST_GETATTR, NULL); 
        printf("result: %d\n", rc); 
+
+       printf("readpage test... ");
+       rc = ioctl(fd, IOC_REQUEST_READPAGE, NULL); 
+       printf("result: %d\n", rc); 
        return 0;
 }