aboutsummaryrefslogtreecommitdiff
path: root/fs/minix/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/minix/dir.c')
-rw-r--r--fs/minix/dir.c78
1 files changed, 30 insertions, 48 deletions
diff --git a/fs/minix/dir.c b/fs/minix/dir.c
index 6198731d7fc..dfaf6fa9b7b 100644
--- a/fs/minix/dir.c
+++ b/fs/minix/dir.c
@@ -16,13 +16,13 @@
typedef struct minix_dir_entry minix_dirent;
typedef struct minix3_dir_entry minix3_dirent;
-static int minix_readdir(struct file *, void *, filldir_t);
+static int minix_readdir(struct file *, struct dir_context *);
const struct file_operations minix_dir_operations = {
.llseek = generic_file_llseek,
.read = generic_read_dir,
- .readdir = minix_readdir,
- .fsync = simple_fsync,
+ .iterate = minix_readdir,
+ .fsync = generic_file_fsync,
};
static inline void dir_put_page(struct page *page)
@@ -72,16 +72,9 @@ static struct page * dir_get_page(struct inode *dir, unsigned long n)
{
struct address_space *mapping = dir->i_mapping;
struct page *page = read_mapping_page(mapping, n, NULL);
- if (!IS_ERR(page)) {
+ if (!IS_ERR(page))
kmap(page);
- if (!PageUptodate(page))
- goto fail;
- }
return page;
-
-fail:
- dir_put_page(page);
- return ERR_PTR(-EIO);
}
static inline void *minix_next_entry(void *de, struct minix_sb_info *sbi)
@@ -89,22 +82,23 @@ static inline void *minix_next_entry(void *de, struct minix_sb_info *sbi)
return (void*)((char*)de + sbi->s_dirsize);
}
-static int minix_readdir(struct file * filp, void * dirent, filldir_t filldir)
+static int minix_readdir(struct file *file, struct dir_context *ctx)
{
- unsigned long pos = filp->f_pos;
- struct inode *inode = filp->f_path.dentry->d_inode;
+ struct inode *inode = file_inode(file);
struct super_block *sb = inode->i_sb;
- unsigned offset = pos & ~PAGE_CACHE_MASK;
- unsigned long n = pos >> PAGE_CACHE_SHIFT;
- unsigned long npages = dir_pages(inode);
struct minix_sb_info *sbi = minix_sb(sb);
unsigned chunk_size = sbi->s_dirsize;
- char *name;
- __u32 inumber;
+ unsigned long npages = dir_pages(inode);
+ unsigned long pos = ctx->pos;
+ unsigned offset;
+ unsigned long n;
- pos = (pos + chunk_size-1) & ~(chunk_size-1);
+ ctx->pos = pos = ALIGN(pos, chunk_size);
if (pos >= inode->i_size)
- goto done;
+ return 0;
+
+ offset = pos & ~PAGE_CACHE_MASK;
+ n = pos >> PAGE_CACHE_SHIFT;
for ( ; n < npages; n++, offset = 0) {
char *p, *kaddr, *limit;
@@ -116,6 +110,8 @@ static int minix_readdir(struct file * filp, void * dirent, filldir_t filldir)
p = kaddr+offset;
limit = kaddr + minix_last_byte(inode, n) - chunk_size;
for ( ; p <= limit; p = minix_next_entry(p, sbi)) {
+ const char *name;
+ __u32 inumber;
if (sbi->s_version == MINIX_V3) {
minix3_dirent *de3 = (minix3_dirent *)p;
name = de3->name;
@@ -126,24 +122,17 @@ static int minix_readdir(struct file * filp, void * dirent, filldir_t filldir)
inumber = de->inode;
}
if (inumber) {
- int over;
-
unsigned l = strnlen(name, sbi->s_namelen);
- offset = p - kaddr;
- over = filldir(dirent, name, l,
- (n << PAGE_CACHE_SHIFT) | offset,
- inumber, DT_UNKNOWN);
- if (over) {
+ if (!dir_emit(ctx, name, l,
+ inumber, DT_UNKNOWN)) {
dir_put_page(page);
- goto done;
+ return 0;
}
}
+ ctx->pos += chunk_size;
}
dir_put_page(page);
}
-
-done:
- filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset;
return 0;
}
@@ -278,8 +267,7 @@ int minix_add_link(struct dentry *dentry, struct inode *inode)
got_it:
pos = page_offset(page) + p - (char *)page_address(page);
- err = __minix_write_begin(NULL, page->mapping, pos, sbi->s_dirsize,
- AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
+ err = minix_prepare_chunk(page, pos, sbi->s_dirsize);
if (err)
goto out_unlock;
memcpy (namx, name, namelen);
@@ -304,8 +292,7 @@ out_unlock:
int minix_delete_entry(struct minix_dir_entry *de, struct page *page)
{
- struct address_space *mapping = page->mapping;
- struct inode *inode = (struct inode*)mapping->host;
+ struct inode *inode = page->mapping->host;
char *kaddr = page_address(page);
loff_t pos = page_offset(page) + (char*)de - kaddr;
struct minix_sb_info *sbi = minix_sb(inode->i_sb);
@@ -313,8 +300,7 @@ int minix_delete_entry(struct minix_dir_entry *de, struct page *page)
int err;
lock_page(page);
- err = __minix_write_begin(NULL, mapping, pos, len,
- AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
+ err = minix_prepare_chunk(page, pos, len);
if (err == 0) {
if (sbi->s_version == MINIX_V3)
((minix3_dirent *) de)->inode = 0;
@@ -332,22 +318,20 @@ int minix_delete_entry(struct minix_dir_entry *de, struct page *page)
int minix_make_empty(struct inode *inode, struct inode *dir)
{
- struct address_space *mapping = inode->i_mapping;
- struct page *page = grab_cache_page(mapping, 0);
+ struct page *page = grab_cache_page(inode->i_mapping, 0);
struct minix_sb_info *sbi = minix_sb(inode->i_sb);
char *kaddr;
int err;
if (!page)
return -ENOMEM;
- err = __minix_write_begin(NULL, mapping, 0, 2 * sbi->s_dirsize,
- AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
+ err = minix_prepare_chunk(page, 0, 2 * sbi->s_dirsize);
if (err) {
unlock_page(page);
goto fail;
}
- kaddr = kmap_atomic(page, KM_USER0);
+ kaddr = kmap_atomic(page);
memset(kaddr, 0, PAGE_CACHE_SIZE);
if (sbi->s_version == MINIX_V3) {
@@ -367,7 +351,7 @@ int minix_make_empty(struct inode *inode, struct inode *dir)
de->inode = dir->i_ino;
strcpy(de->name, "..");
}
- kunmap_atomic(kaddr, KM_USER0);
+ kunmap_atomic(kaddr);
err = dir_commit_chunk(page, 0, 2 * sbi->s_dirsize);
fail:
@@ -432,8 +416,7 @@ not_empty:
void minix_set_link(struct minix_dir_entry *de, struct page *page,
struct inode *inode)
{
- struct address_space *mapping = page->mapping;
- struct inode *dir = mapping->host;
+ struct inode *dir = page->mapping->host;
struct minix_sb_info *sbi = minix_sb(dir->i_sb);
loff_t pos = page_offset(page) +
(char *)de-(char*)page_address(page);
@@ -441,8 +424,7 @@ void minix_set_link(struct minix_dir_entry *de, struct page *page,
lock_page(page);
- err = __minix_write_begin(NULL, mapping, pos, sbi->s_dirsize,
- AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
+ err = minix_prepare_chunk(page, pos, sbi->s_dirsize);
if (err == 0) {
if (sbi->s_version == MINIX_V3)
((minix3_dirent *) de)->inode = inode->i_ino;