From dfe6b1adaedec5d6c7ae7220c2dfaf8236631eca Mon Sep 17 00:00:00 2001 From: braam Date: Mon, 21 Jan 2002 23:58:26 +0000 Subject: [PATCH] assorted bug fixes and a working directory readpage routine for Lustre Light. --- lustre/include/linux/lustre_idl.h | 15 ++++ lustre/include/linux/lustre_light.h | 4 +- lustre/include/linux/lustre_mds.h | 20 ++--- lustre/include/linux/obdo.h | 1 - lustre/lib/mds_pack.c | 4 +- lustre/llite/dir.c | 3 + lustre/llite/namei.c | 26 +++---- lustre/llite/rw.c | 88 ++++++++++++++------- lustre/llite/super.c | 48 +++--------- lustre/mdc/mdc_request.c | 77 +++++++++++++++++-- lustre/mds/handler.c | 148 +++++++++++++++++++++++++++++++----- lustre/obdfs/super.c | 2 +- lustre/tests/llmount.sh | 8 +- lustre/tests/mdcreq.sh | 2 +- lustre/tests/testreq.c | 7 +- 15 files changed, 327 insertions(+), 126 deletions(-) diff --git a/lustre/include/linux/lustre_idl.h b/lustre/include/linux/lustre_idl.h index 4713905..5b9b033 100644 --- a/lustre/include/linux/lustre_idl.h +++ b/lustre/include/linux/lustre_idl.h @@ -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; diff --git a/lustre/include/linux/lustre_light.h b/lustre/include/linux/lustre_light.h index 1fea41d..77244d2 100644 --- a/lustre/include/linux/lustre_light.h +++ b/lustre/include/linux/lustre_light.h @@ -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 */ diff --git a/lustre/include/linux/lustre_mds.h b/lustre/include/linux/lustre_mds.h index c018d75..4891588 100644 --- a/lustre/include/linux/lustre_mds.h +++ b/lustre/include/linux/lustre_mds.h @@ -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 diff --git a/lustre/include/linux/obdo.h b/lustre/include/linux/obdo.h index a111fd5..4255482 100644 --- a/lustre/include/linux/obdo.h +++ b/lustre/include/linux/obdo.h @@ -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 */ diff --git a/lustre/lib/mds_pack.c b/lustre/lib/mds_pack.c index 86d78e0..f13eaa4 100644 --- a/lustre/lib/mds_pack.c +++ b/lustre/lib/mds_pack.c @@ -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 ) { diff --git a/lustre/llite/dir.c b/lustre/llite/dir.c index 12be7a2..f07a310 100644 --- a/lustre/llite/dir.c +++ b/lustre/llite/dir.c @@ -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; diff --git a/lustre/llite/namei.c b/lustre/llite/namei.c index 9dc1050..15bd677 100644 --- a/lustre/llite/namei.c +++ b/lustre/llite/namei.c @@ -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); diff --git a/lustre/llite/rw.c b/lustre/llite/rw.c index a20f267..46eaee8 100644 --- a/lustre/llite/rw.c +++ b/lustre/llite/rw.c @@ -33,6 +33,9 @@ #include #include +#include +#include +#include #include 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 +}; diff --git a/lustre/llite/super.c b/lustre/llite/super.c index d788210..43f3457 100644 --- a/lustre/llite/super.c +++ b/lustre/llite/super.c @@ -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 }; diff --git a/lustre/mdc/mdc_request.c b/lustre/mdc/mdc_request.c index 07ce317..ac1f6ac 100644 --- a/lustre/mdc/mdc_request.c +++ b/lustre/mdc/mdc_request.c @@ -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); diff --git a/lustre/mds/handler.c b/lustre/mds/handler.c index f272a2cc..3a29163 100644 --- a/lustre/mds/handler.c +++ b/lustre/mds/handler.c @@ -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); diff --git a/lustre/obdfs/super.c b/lustre/obdfs/super.c index 93a8600..2422881 100644 --- a/lustre/obdfs/super.c +++ b/lustre/obdfs/super.c @@ -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; diff --git a/lustre/tests/llmount.sh b/lustre/tests/llmount.sh index bd3e04c..703e10f 100755 --- a/lustre/tests/llmount.sh +++ b/lustre/tests/llmount.sh @@ -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 diff --git a/lustre/tests/mdcreq.sh b/lustre/tests/mdcreq.sh index 42c623b8..4625991 100644 --- a/lustre/tests/mdcreq.sh +++ b/lustre/tests/mdcreq.sh @@ -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 diff --git a/lustre/tests/testreq.c b/lustre/tests/testreq.c index b47b31c..98886f4 100644 --- a/lustre/tests/testreq.c +++ b/lustre/tests/testreq.c @@ -3,8 +3,8 @@ #include #include #include - #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; } -- 1.8.3.1