From bca31f81bcacf7a528d35fa9ef4140f33252be5f Mon Sep 17 00:00:00 2001 From: adilger Date: Fri, 22 Mar 2002 21:28:27 +0000 Subject: [PATCH] The ext3 MDS code. Basically, we have to hack around the fact that ext3 does not have the directories in page cache, so we need to export the ext3_bread() function in order to ensure we read the same data as what the filesystem itself is using. This will likely go away at some time in the future as ext3 is ported to the pure page-cache-based directory handling that is in ext2 (which is slightly more efficient). --- lustre/mds/handler.c | 59 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 49 insertions(+), 10 deletions(-) diff --git a/lustre/mds/handler.c b/lustre/mds/handler.c index d788b57..394439e 100644 --- a/lustre/mds/handler.c +++ b/lustre/mds/handler.c @@ -33,6 +33,9 @@ #include #include +struct buffer_head *ext3_bread(void *handle, struct inode *inode, + int block, int create, int *err); + int mds_sendpage(struct ptlrpc_request *req, struct file *file, __u64 offset, struct niobuf *dst) { @@ -40,11 +43,33 @@ int mds_sendpage(struct ptlrpc_request *req, struct file *file, mm_segment_t oldfs = get_fs(); if (req->rq_peer.peer_nid == 0) { + struct inode *inode = file->f_dentry->d_inode; + char *buf = (char *)(long)dst->addr; + /* dst->addr is a user address, but in a different task! */ set_fs(KERNEL_DS); - /* FIXME: Can't use file->f_op->read() on a directory */ - rc = generic_file_read(file, (char *)(long)dst->addr, - PAGE_SIZE, &offset); + /* FIXME: we need to use ext3_bread because ext3 does not + * have the directories in page cache yet. If we + * just use generic_file_read() then the pages we + * get are in a different address space than those + * used by the filesystem == cache incoherency. + */ + if (S_ISREG(inode->i_mode)) + rc = file->f_op->read(file, buf, PAGE_SIZE, &offset); + else if (!strcmp(inode->i_sb->s_type->name, "ext3")) { + struct buffer_head *bh; + + bh = ext3_bread(NULL, inode, offset >> inode->i_blkbits, + 0, &rc); + + if (bh) { + memcpy(buf, bh->b_data, inode->i_blksize); + brelse(bh); + rc = inode->i_blksize; + } + } else + rc = generic_file_read(file, buf, PAGE_SIZE, &offset); + set_fs(oldfs); if (rc != PAGE_SIZE) { @@ -53,8 +78,9 @@ int mds_sendpage(struct ptlrpc_request *req, struct file *file, } EXIT; } else { + struct inode *inode = file->f_dentry->d_inode; struct ptlrpc_bulk_desc *bulk; - char *buf = NULL; + char *buf; bulk = ptlrpc_prep_bulk(&req->rq_peer); if (bulk == NULL) { @@ -71,9 +97,23 @@ int mds_sendpage(struct ptlrpc_request *req, struct file *file, } set_fs(KERNEL_DS); - /* FIXME: Can't use file->f_op->read() on a directory */ - //rc = file->f_op->read(file, buf, PAGE_SIZE, &offset); - rc = generic_file_read(file, buf, PAGE_SIZE, &offset); + /* FIXME: see comments above */ + if (S_ISREG(inode->i_mode)) + rc = file->f_op->read(file, buf, PAGE_SIZE, &offset); + else if (!strcmp(inode->i_sb->s_type->name, "ext3")) { + struct buffer_head *bh; + + bh = ext3_bread(NULL, inode, offset >> inode->i_blkbits, + 0, &rc); + + if (bh) { + memcpy(buf, bh->b_data, inode->i_blksize); + brelse(bh); + rc = inode->i_blksize; + } + } else + rc = generic_file_read(file, buf, PAGE_SIZE, &offset); + set_fs(oldfs); if (rc != PAGE_SIZE) { @@ -124,9 +164,8 @@ struct dentry *mds_fid2dentry(struct mds_obd *mds, struct ll_fid *fid, CDEBUG(D_DENTRY, "--> mds_fid2dentry: sb %p\n", inode->i_sb); - if (is_bad_inode(inode) - || (generation && inode->i_generation != generation) - ) { + if (is_bad_inode(inode) || + (generation && inode->i_generation != generation)) { /* we didn't find the right inode.. */ CERROR("bad inode %lu, link: %d ct: %d or version %u/%u\n", inode->i_ino, -- 1.8.3.1