*
* 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.
*
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
-#include <sys/fcntl.h>
+#include <fcntl.h>
#include <sys/queue.h>
+#ifdef HAVE_XTIO_H
+#include <xtio.h>
+#endif
#include <sysio.h>
#include <fs.h>
#include <mount.h>
#include <inode.h>
+#ifdef HAVE_FILE_H
#include <file.h>
+#endif
#undef LIST_HEAD
-#include <linux/types.h>
-#include <linux/dirent.h>
+#ifdef HAVE_ASM_TYPES_H
+#include <asm/types.h>
+#elif defined(HAVE_SYS_TYPES_H)
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_LINUX_UNISTD_H
#include <linux/unistd.h>
+#elif defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+
+#include <dirent.h>
#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;
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} };
+ { .name = {st->st_ino, (__u64)lli->lli_st_generation} };
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_IBITS, &policy, LCK_PR, &lockh);
+ &res_id, LDLM_IBITS, &policy, LCK_CR, &lockh);
if (!rc) {
llu_prepare_mdc_op_data(&data, inode, NULL, NULL, 0, 0);
- rc = mdc_enqueue(sbi->ll_mdc_exp, LDLM_IBITS, &it, LCK_PR,
+ rc = mdc_enqueue(sbi->ll_mdc_exp, LDLM_IBITS, &it, LCK_CR,
&data, &lockh, NULL, 0,
ldlm_completion_ast, llu_mdc_blocking_ast,
- inode);
+ inode, LDLM_FL_CANCEL_ON_BLOCK);
request = (struct ptlrpc_request *)it.d.lustre.it_data;
if (request)
ptlrpc_req_finished(request);
}
ldlm_lock_dump_handle(D_OTHER, &lockh);
- mdc_pack_fid(&mdc_fid, lli->lli_st_ino, lli->lli_st_generation, S_IFDIR);
+ mdc_pack_fid(&mdc_fid, st->st_ino, lli->lli_st_generation, S_IFDIR);
- offset = page->index << PAGE_SHIFT;
+ offset = (__u64)page->index << CFS_PAGE_SHIFT;
rc = mdc_readpage(sbi->ll_mdc_exp, &mdc_fid,
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 mdc_readpage() */
+ /* swabbed by mdc_readpage() */
+ LASSERT_REPSWABBED(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;
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))
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;
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;
+ int filled = 0;
+ unsigned long pgidx, maxpages;
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;
continue;
/* size might have been updated by mdc_readpage */
- maxpages = lli->lli_st_size >> PAGE_CACHE_SHIFT;
+ 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 << CFS_PAGE_SHIFT) | offset)
+ + le16_to_cpu(de->rec_len),
le32_to_cpu(de->inode), d_type, &filled);
if (over) {
free_page(page);
free_page(page);
}
done:
- lli->lli_dir_pos = pgidx << PAGE_CACHE_SHIFT | offset;
+ lli->lli_dir_pos = (__u64)pgidx << CFS_PAGE_SHIFT | offset;
*basep = lli->lli_dir_pos;
+ liblustre_wait_event(0);
RETURN(filled);
}