X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Fliblustre%2Fdir.c;h=0f2bc905b71a7b045b0a9f31d9c532e6220fe95b;hp=c236d730e35a56b83bfbf83dc97f799ca6269b43;hb=a25adb47c7b7eeb68a922e2647d74eeff3401c6a;hpb=a1d11a561dea2ae38275eedc64d09e1fe1730d6b diff --git a/lustre/liblustre/dir.c b/lustre/liblustre/dir.c index c236d73..0f2bc90 100644 --- a/lustre/liblustre/dir.c +++ b/lustre/liblustre/dir.c @@ -1,9 +1,9 @@ /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- * vim:expandtab:shiftwidth=8:tabstop=8: * - * Lustre Light Super operations + * Lustre Light directory handling * - * Copyright (c) 2002, 2003 Cluster File Systems, Inc. + * Copyright (c) 2002-2004 Cluster File Systems, Inc. * * This file is part of Lustre, http://www.lustre.org. * @@ -30,59 +30,65 @@ #include #include #include -#include +#include #include #include +#ifdef HAVE_XTIO_H +#include +#endif #include #include #include +#ifdef HAVE_FILE_H #include +#endif #undef LIST_HEAD -#include -#include +#ifdef HAVE_ASM_TYPES_H +#include +#elif defined(HAVE_SYS_TYPES_H) +#include +#endif + +#ifdef HAVE_LINUX_UNISTD_H #include +#elif defined(HAVE_UNISTD_H) +#include +#endif + +#include #include "llite_lib.h" static int llu_dir_do_readpage(struct inode *inode, struct page *page) { struct llu_inode_info *lli = llu_i2info(inode); + struct intnl_stat *st = llu_i2stat(inode); struct llu_sb_info *sbi = llu_i2sbi(inode); - struct ll_fid mdc_fid; __u64 offset; int rc = 0; struct ptlrpc_request *request; struct lustre_handle lockh; - struct mds_body *body; + struct mdt_body *body; struct lookup_intent it = { .it_op = IT_READDIR }; - struct mdc_op_data data; - struct obd_device *obddev = class_exp2obd(sbi->ll_mdc_exp); - struct ldlm_res_id res_id = - { .name = {lli->lli_st_ino, (__u64)lli->lli_st_generation} }; + struct md_op_data op_data; + ldlm_policy_data_t policy = { .l_inodebits = { MDS_INODELOCK_UPDATE } }; ENTRY; - if ((lli->lli_st_size + PAGE_CACHE_SIZE - 1) >> PAGE_SHIFT <= page->index) { - /* XXX why do we need this exactly, and why do we think that - * an all-zero directory page is useful? - */ - CERROR("memsetting dir page %lu to zero (size %lld)\n", - page->index, lli->lli_st_size); - memset(page->addr, 0, PAGE_CACHE_SIZE); - GOTO(readpage_out, rc); - } - - rc = ldlm_lock_match(obddev->obd_namespace, LDLM_FL_BLOCK_GRANTED, - &res_id, LDLM_PLAIN, NULL, LCK_PR, &lockh); + rc = md_lock_match(sbi->ll_md_exp, LDLM_FL_BLOCK_GRANTED, + &lli->lli_fid, LDLM_IBITS, &policy, LCK_CR, &lockh); if (!rc) { - llu_prepare_mdc_op_data(&data, inode, NULL, NULL, 0, 0); + struct ldlm_enqueue_info einfo = {LDLM_IBITS, LCK_CR, + llu_md_blocking_ast, ldlm_completion_ast, NULL, inode}; + + llu_prep_md_op_data(&op_data, inode, NULL, NULL, 0, 0, + LUSTRE_OPC_ANY); - rc = mdc_enqueue(sbi->ll_mdc_exp, LDLM_PLAIN, &it, LCK_PR, - &data, &lockh, NULL, 0, - ldlm_completion_ast, llu_mdc_blocking_ast, - inode); + rc = md_enqueue(sbi->ll_md_exp, &einfo, &it, + &op_data, &lockh, NULL, 0, + LDLM_FL_CANCEL_ON_BLOCK); request = (struct ptlrpc_request *)it.d.lustre.it_data; if (request) ptlrpc_req_finished(request); @@ -93,33 +99,34 @@ static int llu_dir_do_readpage(struct inode *inode, struct page *page) } ldlm_lock_dump_handle(D_OTHER, &lockh); - mdc_pack_fid(&mdc_fid, lli->lli_st_ino, lli->lli_st_generation, S_IFDIR); - - offset = page->index << PAGE_SHIFT; - rc = mdc_readpage(sbi->ll_mdc_exp, &mdc_fid, - offset, page, &request); + offset = (__u64)page->index << CFS_PAGE_SHIFT; + rc = md_readpage(sbi->ll_md_exp, &lli->lli_fid, NULL, + offset, page, &request); if (!rc) { - body = lustre_msg_buf(request->rq_repmsg, 0, sizeof (*body)); - LASSERT (body != NULL); /* checked by mdc_readpage() */ - LASSERT_REPSWABBED (request, 0); /* swabbed by mdc_readpage() */ - - lli->lli_st_size = body->size; + body = lustre_msg_buf(request->rq_repmsg, REPLY_REC_OFF, + sizeof(*body)); + LASSERT(body != NULL); /* checked by md_readpage() */ + /* swabbed by md_readpage() */ + LASSERT(lustre_rep_swabbed(request, REPLY_REC_OFF)); + + st->st_size = body->size; + } else { + CERROR("read_dir_page(%ld) error %d\n", page->index, rc); } ptlrpc_req_finished(request); EXIT; - readpage_out: - ldlm_lock_decref(&lockh, LCK_PR); + ldlm_lock_decref(&lockh, LCK_CR); return rc; } -static struct page *llu_dir_read_page(struct inode *ino, int pgidx) +static struct page *llu_dir_read_page(struct inode *ino, unsigned long pgidx) { struct page *page; int rc; ENTRY; - page = alloc_page(0); + page = cfs_alloc_page(0); if (!page) { CERROR("alloc page failed\n"); RETURN(ERR_PTR(-ENOMEM)); @@ -135,6 +142,29 @@ static struct page *llu_dir_read_page(struct inode *ino, int pgidx) return page; } +enum { + EXT2_FT_UNKNOWN, + EXT2_FT_REG_FILE, + EXT2_FT_DIR, + EXT2_FT_CHRDEV, + EXT2_FT_BLKDEV, + EXT2_FT_FIFO, + EXT2_FT_SOCK, + EXT2_FT_SYMLINK, + EXT2_FT_MAX +}; + +static unsigned char ext2_filetype_table[EXT2_FT_MAX] = { + [EXT2_FT_UNKNOWN] DT_UNKNOWN, + [EXT2_FT_REG_FILE] DT_REG, + [EXT2_FT_DIR] DT_DIR, + [EXT2_FT_CHRDEV] DT_CHR, + [EXT2_FT_BLKDEV] DT_BLK, + [EXT2_FT_FIFO] DT_FIFO, + [EXT2_FT_SOCK] DT_SOCK, + [EXT2_FT_SYMLINK] DT_LNK, +}; + #define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de))) #define ROUND_UP64(x) (((x)+sizeof(__u64)-1) & ~(sizeof(__u64)-1)) @@ -150,9 +180,11 @@ static int filldir(char *buf, int buflen, return 1; dirent->d_ino = ino; - dirent->d_off = offset, + dirent->d_off = offset; dirent->d_reclen = reclen; +#ifndef _AIX dirent->d_type = (unsigned short) d_type; +#endif memcpy(dirent->d_name, name, namelen); dirent->d_name[namelen] = 0; @@ -161,20 +193,29 @@ static int filldir(char *buf, int buflen, return 0; } -ssize_t llu_iop_getdirentries(struct inode *ino, char *buf, size_t nbytes, - _SYSIO_OFF_T *basep) +ssize_t llu_iop_filldirentries(struct inode *ino, _SYSIO_OFF_T *basep, + char *buf, size_t nbytes) { struct llu_inode_info *lli = llu_i2info(ino); + struct intnl_stat *st = llu_i2stat(ino); loff_t pos = *basep, offset; - int maxpages, pgidx, filled = 0; + unsigned long maxpages, pgidx; + int filled = 0; ENTRY; + liblustre_wait_event(0); + + if (st->st_size == 0) { + CWARN("dir size is 0?\n"); + RETURN(0); + } + if (pos == -1) pos = lli->lli_dir_pos; - maxpages = lli->lli_st_size >> PAGE_CACHE_SHIFT; - pgidx = pos >> PAGE_CACHE_SHIFT; - offset = pos & ~PAGE_CACHE_MASK; + maxpages = (st->st_size + CFS_PAGE_SIZE - 1) >> CFS_PAGE_SHIFT; + pgidx = pos >> CFS_PAGE_SHIFT; + offset = pos & ~CFS_PAGE_MASK; for ( ; pgidx < maxpages ; pgidx++, offset = 0) { struct page *page; @@ -185,27 +226,36 @@ ssize_t llu_iop_getdirentries(struct inode *ino, char *buf, size_t nbytes, if (IS_ERR(page)) continue; - /* size might have been updated by mdc_readpage */ - maxpages = lli->lli_st_size >> PAGE_CACHE_SHIFT; + /* size might have been updated by md_readpage */ + maxpages = (st->st_size + CFS_PAGE_SIZE - 1) >> CFS_PAGE_SHIFT; /* fill in buffer */ addr = page->addr; - limit = addr + PAGE_CACHE_SIZE - EXT2_DIR_REC_LEN(1); + limit = addr + CFS_PAGE_SIZE - EXT2_DIR_REC_LEN(1); de = (struct ext2_dirent *) (addr + offset); for ( ; (char*) de <= limit; de = ext2_next_entry(de)) { if (de->inode) { int over; - unsigned char d_type = 0; + unsigned char d_type = DT_UNKNOWN; - /* XXX handle type, etc here */ + if (de->file_type < EXT2_FT_MAX) + d_type = ext2_filetype_table[de->file_type]; offset = (char*) de - addr; over = filldir(buf, nbytes, de->name, de->name_len, - (pgidx << PAGE_CACHE_SHIFT) | offset, + (((__u64)pgidx << PAGE_SHIFT) | offset) + + le16_to_cpu(de->rec_len), le32_to_cpu(de->inode), d_type, &filled); if (over) { free_page(page); + /* + * if buffer overflow with no data + * returned yet, then report error + * instead of eof + */ + if (filled == 0) + RETURN(-EINVAL); GOTO(done, 0); } } @@ -214,7 +264,8 @@ ssize_t llu_iop_getdirentries(struct inode *ino, char *buf, size_t nbytes, free_page(page); } done: - lli->lli_dir_pos = pgidx << PAGE_CACHE_SHIFT | offset; + lli->lli_dir_pos = pgidx << CFS_PAGE_SHIFT | offset; *basep = lli->lli_dir_pos; + liblustre_wait_event(0); RETURN(filled); }