X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fllite%2Fdir.c;h=456f6f1091c9aba57f69565556270a8fb466708c;hb=846ef92f3ea8e6d22920031ebc42848e493b13da;hp=09e2bba69cb0c32f3f6e944abf3918782feff1a1;hpb=9806643df885c94d1984204e2d71325a5aa1506f;p=fs%2Flustre-release.git diff --git a/lustre/llite/dir.c b/lustre/llite/dir.c index 09e2bba..456f6f1 100644 --- a/lustre/llite/dir.c +++ b/lustre/llite/dir.c @@ -20,10 +20,10 @@ * * All code that works with directory layout had been switched to pagecache * and moved here. AV - * + * * Adapted for Lustre Light * Copyright (C) 2002, Cluster File Systems, Inc. - * + * */ #include @@ -41,6 +41,7 @@ #include #include #include +#include typedef struct ext2_dir_entry_2 ext2_dirent; @@ -61,28 +62,44 @@ static int ll_dir_readpage(struct file *file, struct page *page) char *buf; __u64 offset; int rc = 0; - struct ptlrpc_request *request = NULL; + struct ptlrpc_request *request; + struct lustre_handle lockh; + struct mds_body *body; + struct lookup_intent it = {IT_READDIR}; ENTRY; if ((inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_SHIFT <= page->index){ memset(kmap(page), 0, PAGE_CACHE_SIZE); kunmap(page); - EXIT; - goto readpage_out; + GOTO(readpage_out, rc); + } + + rc = ll_lock(inode, NULL, &it, &lockh); + request = (struct ptlrpc_request *)it.it_data; + ptlrpc_free_req(request); + if (rc != ELDLM_OK) { + CERROR("lock enqueue: err: %d\n", rc); + UnlockPage(page); + RETURN(rc); } + ldlm_lock_dump((void *)(unsigned long)lockh.addr); if (Page_Uptodate(page)) { CERROR("Explain this please?\n"); - EXIT; - goto readpage_out; + GOTO(readpage_out, rc); } - offset = page->index << PAGE_SHIFT; + offset = page->index << PAGE_SHIFT; buf = kmap(page); - rc = mdc_readpage(&sbi->ll_mds_client, sbi->ll_mds_conn, inode->i_ino, + rc = mdc_readpage(&sbi->ll_mdc_conn, inode->i_ino, S_IFDIR, offset, buf, &request); - kunmap(page); + kunmap(page); + body = lustre_msg_buf(request->rq_repmsg, 0); + if (!body) + rc = -EINVAL; + if (body) + inode->i_size = body->size; ptlrpc_free_req(request); EXIT; @@ -91,6 +108,9 @@ static int ll_dir_readpage(struct file *file, struct page *page) SetPageUptodate(page); UnlockPage(page); + rc = ll_unlock(LCK_PR, &lockh); + if (rc != ELDLM_OK) + CERROR("ll_unlock: err: %d\n", rc); return rc; } /* ll_dir_readpage */ @@ -119,8 +139,7 @@ int waitfor_one_page(struct page *page) */ static inline unsigned ext2_chunk_size(struct inode *inode) { - //return inode->i_sb->s_blocksize; - return PAGE_CACHE_SIZE; + return inode->i_sb->s_blocksize; } static inline void ext2_put_page(struct page *page) @@ -134,7 +153,7 @@ static inline unsigned long dir_pages(struct inode *inode) return (inode->i_size+PAGE_CACHE_SIZE-1)>>PAGE_CACHE_SHIFT; } -extern void set_page_clean(struct page *page); +extern void set_page_clean(struct page *page); static int ext2_commit_chunk(struct page *page, unsigned from, unsigned to) { @@ -168,13 +187,15 @@ static void ext2_check_page(struct page *page) if ((dir->i_size >> PAGE_CACHE_SHIFT) == page->index) { limit = dir->i_size & ~PAGE_CACHE_MASK; if (limit & (chunk_size - 1)) { - CERROR("limit %d dir size %lld index %ld\n", - limit, dir->i_size, page->index); + CERROR("limit %d dir size %lld index %ld\n", + limit, dir->i_size, page->index); goto Ebadsize; } for (offs = limit; offsrec_len = cpu_to_le16(chunk_size); + p->name_len = 0; + p->inode = 0; } if (!limit) goto out; @@ -287,7 +308,7 @@ static inline ext2_dirent *ext2_next_entry(ext2_dirent *p) return (ext2_dirent *)((char*)p + le16_to_cpu(p->rec_len)); } -static inline unsigned +static inline unsigned ext2_validate_entry(char *base, unsigned offset, unsigned mask) { ext2_dirent *de = (ext2_dirent*)(base + offset); @@ -309,16 +330,16 @@ static unsigned char ext2_filetype_table[EXT2_FT_MAX] = { }; static unsigned int ll_dt2fmt[DT_WHT + 1] = { - [EXT2_FT_UNKNOWN] 0, + [EXT2_FT_UNKNOWN] 0, [EXT2_FT_REG_FILE] S_IFREG, [EXT2_FT_DIR] S_IFDIR, [EXT2_FT_CHRDEV] S_IFCHR, - [EXT2_FT_BLKDEV] S_IFBLK, + [EXT2_FT_BLKDEV] S_IFBLK, [EXT2_FT_FIFO] S_IFIFO, [EXT2_FT_SOCK] S_IFSOCK, [EXT2_FT_SYMLINK] S_IFLNK }; - + #define S_SHIFT 12 static unsigned char ext2_type_by_mode[S_IFMT >> S_SHIFT] = { [S_IFREG >> S_SHIFT] EXT2_FT_REG_FILE, @@ -336,8 +357,7 @@ static inline void ext2_set_de_type(ext2_dirent *de, struct inode *inode) de->file_type = ext2_type_by_mode[(mode & S_IFMT)>>S_SHIFT]; } -int -new_ll_readdir (struct file * filp, void * dirent, filldir_t filldir) +int ll_readdir(struct file * filp, void * dirent, filldir_t filldir) { loff_t pos = filp->f_pos; struct inode *inode = filp->f_dentry->d_inode; @@ -348,6 +368,7 @@ new_ll_readdir (struct file * filp, void * dirent, filldir_t filldir) unsigned chunk_mask = ~(ext2_chunk_size(inode)-1); unsigned char *types = NULL; int need_revalidate = (filp->f_version != inode->i_version); + ENTRY; if (pos > inode->i_size - EXT2_DIR_REC_LEN(1)) GOTO(done, 0); @@ -359,6 +380,9 @@ new_ll_readdir (struct file * filp, void * dirent, filldir_t filldir) ext2_dirent *de; struct page *page = ext2_get_page(inode, n); + /* size might have been updated by mdc_readpage */ + npages = dir_pages(inode); + if (IS_ERR(page)) continue; kaddr = page_address(page); @@ -392,7 +416,7 @@ done: filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset; filp->f_version = inode->i_version; UPDATE_ATIME(inode); - return 0; + RETURN(0); } /* @@ -459,12 +483,12 @@ struct ext2_dir_entry_2 * ext2_dotdot (struct inode *dir, struct page **p) return de; } -ino_t ll_inode_by_name(struct inode * dir, struct dentry *dentry, int *type) +obd_id ll_inode_by_name(struct inode * dir, struct dentry *dentry, int *type) { - ino_t res = 0; + obd_id res = 0; struct ext2_dir_entry_2 * de; struct page *page; - + de = ext2_find_entry (dir, dentry, &page); if (de) { res = le32_to_cpu(de->inode); @@ -625,12 +649,14 @@ int ext2_make_empty(struct inode *inode, struct inode *parent) if (!page) return -ENOMEM; + base = kmap(page); + if (!base) + return -ENOMEM; + err = mapping->a_ops->prepare_write(NULL, page, 0, chunk_size); if (err) goto fail; - base = page_address(page); - de = (struct ext2_dir_entry_2 *) base; de->name_len = 1; de->rec_len = cpu_to_le16(EXT2_DIR_REC_LEN(1)); @@ -647,6 +673,7 @@ int ext2_make_empty(struct inode *inode, struct inode *parent) err = ext2_commit_chunk(page, 0, chunk_size); fail: + kunmap(page); UnlockPage(page); page_cache_release(page); ENTRY; @@ -660,7 +687,7 @@ int ext2_empty_dir (struct inode * inode) { struct page *page = NULL; unsigned long i, npages = dir_pages(inode); - + for (i = 0; i < npages; i++) { char *kaddr; ext2_dirent * de; @@ -700,5 +727,5 @@ not_empty: struct file_operations ll_dir_operations = { read: generic_read_dir, - readdir: new_ll_readdir + readdir: ll_readdir };