-/*
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
*
* Copyright (C) 1992, 1993, 1994, 1995
* Remy Card (card@masi.ibp.fr)
*
* 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 <linux/fs.h>
#include <linux/lustre_idl.h>
#include <linux/lustre_mds.h>
#include <linux/lustre_lite.h>
+#include <linux/lustre_dlm.h>
typedef struct ext2_dir_entry_2 ext2_dirent;
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) {
+ 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;
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 */
*/
static inline unsigned ext2_chunk_size(struct inode *inode)
{
- //return inode->i_sb->s_blocksize;
- return PAGE_SIZE;
+ return inode->i_sb->s_blocksize;
}
static inline void ext2_put_page(struct page *page)
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)
{
struct inode *dir = page->mapping->host;
+ loff_t new_size = (page->index << PAGE_CACHE_SHIFT) + to;
int err = 0;
dir->i_version = ++event;
- dir->i_size = (page->index << PAGE_CACHE_SHIFT) + to;
+ if (new_size > dir->i_size)
+ dir->i_size = new_size;
SetPageUptodate(page);
set_page_clean(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; offs<PAGE_CACHE_SIZE; offs += chunk_size) {
ext2_dirent *p = (ext2_dirent*)(kaddr + offs);
p->rec_len = cpu_to_le16(chunk_size);
+ p->name_len = 0;
+ p->inode = 0;
}
if (!limit)
goto out;
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);
};
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,
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;
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;
+ GOTO(done, 0);
types = ext2_filetype_table;
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);
le32_to_cpu(de->inode), d_type);
if (over) {
ext2_put_page(page);
- goto done;
+ GOTO(done,0);
}
}
ext2_put_page(page);
filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset;
filp->f_version = inode->i_version;
UPDATE_ATIME(inode);
- return 0;
+ RETURN(0);
}
/*
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);
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));
err = ext2_commit_chunk(page, 0, chunk_size);
fail:
+ kunmap(page);
UnlockPage(page);
page_cache_release(page);
ENTRY;
{
struct page *page = NULL;
unsigned long i, npages = dir_pages(inode);
-
+
for (i = 0; i < npages; i++) {
char *kaddr;
ext2_dirent * de;
struct file_operations ll_dir_operations = {
read: generic_read_dir,
- readdir: new_ll_readdir
+ readdir: ll_readdir
};