aboutsummaryrefslogtreecommitdiff
path: root/fs/omfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/omfs')
-rw-r--r--fs/omfs/dir.c94
-rw-r--r--fs/omfs/file.c30
-rw-r--r--fs/omfs/inode.c3
3 files changed, 59 insertions, 68 deletions
diff --git a/fs/omfs/dir.c b/fs/omfs/dir.c
index fb5b3ff79dc..1b8e9e8405b 100644
--- a/fs/omfs/dir.c
+++ b/fs/omfs/dir.c
@@ -327,26 +327,23 @@ int omfs_is_bad(struct omfs_sb_info *sbi, struct omfs_header *header,
return is_bad;
}
-static int omfs_fill_chain(struct file *filp, void *dirent, filldir_t filldir,
+static bool omfs_fill_chain(struct inode *dir, struct dir_context *ctx,
u64 fsblock, int hindex)
{
- struct inode *dir = filp->f_dentry->d_inode;
- struct buffer_head *bh;
- struct omfs_inode *oi;
- u64 self;
- int res = 0;
- unsigned char d_type;
-
/* follow chain in this bucket */
while (fsblock != ~0) {
- bh = omfs_bread(dir->i_sb, fsblock);
+ struct buffer_head *bh = omfs_bread(dir->i_sb, fsblock);
+ struct omfs_inode *oi;
+ u64 self;
+ unsigned char d_type;
+
if (!bh)
- goto out;
+ return true;
oi = (struct omfs_inode *) bh->b_data;
if (omfs_is_bad(OMFS_SB(dir->i_sb), &oi->i_head, fsblock)) {
brelse(bh);
- goto out;
+ return true;
}
self = fsblock;
@@ -361,15 +358,16 @@ static int omfs_fill_chain(struct file *filp, void *dirent, filldir_t filldir,
d_type = (oi->i_type == OMFS_DIR) ? DT_DIR : DT_REG;
- res = filldir(dirent, oi->i_name, strnlen(oi->i_name,
- OMFS_NAMELEN), filp->f_pos, self, d_type);
+ if (!dir_emit(ctx, oi->i_name,
+ strnlen(oi->i_name, OMFS_NAMELEN),
+ self, d_type)) {
+ brelse(bh);
+ return false;
+ }
brelse(bh);
- if (res < 0)
- break;
- filp->f_pos++;
+ ctx->pos++;
}
-out:
- return res;
+ return true;
}
static int omfs_rename(struct inode *old_dir, struct dentry *old_dentry,
@@ -403,60 +401,44 @@ out:
return err;
}
-static int omfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
+static int omfs_readdir(struct file *file, struct dir_context *ctx)
{
- struct inode *dir = filp->f_dentry->d_inode;
+ struct inode *dir = file_inode(file);
struct buffer_head *bh;
- loff_t offset, res;
+ __be64 *p;
unsigned int hchain, hindex;
int nbuckets;
- u64 fsblock;
- int ret = -EINVAL;
-
- if (filp->f_pos >> 32)
- goto success;
-
- switch ((unsigned long) filp->f_pos) {
- case 0:
- if (filldir(dirent, ".", 1, 0, dir->i_ino, DT_DIR) < 0)
- goto success;
- filp->f_pos++;
- /* fall through */
- case 1:
- if (filldir(dirent, "..", 2, 1,
- parent_ino(filp->f_dentry), DT_DIR) < 0)
- goto success;
- filp->f_pos = 1 << 20;
- /* fall through */
+
+ if (ctx->pos >> 32)
+ return -EINVAL;
+
+ if (ctx->pos < 1 << 20) {
+ if (!dir_emit_dots(file, ctx))
+ return 0;
+ ctx->pos = 1 << 20;
}
nbuckets = (dir->i_size - OMFS_DIR_START) / 8;
/* high 12 bits store bucket + 1 and low 20 bits store hash index */
- hchain = (filp->f_pos >> 20) - 1;
- hindex = filp->f_pos & 0xfffff;
+ hchain = (ctx->pos >> 20) - 1;
+ hindex = ctx->pos & 0xfffff;
bh = omfs_bread(dir->i_sb, dir->i_ino);
if (!bh)
- goto out;
+ return -EINVAL;
- offset = OMFS_DIR_START + hchain * 8;
+ p = (__be64 *)(bh->b_data + OMFS_DIR_START) + hchain;
- for (; hchain < nbuckets; hchain++, offset += 8) {
- fsblock = be64_to_cpu(*((__be64 *) &bh->b_data[offset]));
-
- res = omfs_fill_chain(filp, dirent, filldir, fsblock, hindex);
- hindex = 0;
- if (res < 0)
+ for (; hchain < nbuckets; hchain++) {
+ __u64 fsblock = be64_to_cpu(*p++);
+ if (!omfs_fill_chain(dir, ctx, fsblock, hindex))
break;
-
- filp->f_pos = (hchain+2) << 20;
+ hindex = 0;
+ ctx->pos = (hchain+2) << 20;
}
brelse(bh);
-success:
- ret = 0;
-out:
- return ret;
+ return 0;
}
const struct inode_operations omfs_dir_inops = {
@@ -470,6 +452,6 @@ const struct inode_operations omfs_dir_inops = {
const struct file_operations omfs_dir_operations = {
.read = generic_read_dir,
- .readdir = omfs_readdir,
+ .iterate = omfs_readdir,
.llseek = generic_file_llseek,
};
diff --git a/fs/omfs/file.c b/fs/omfs/file.c
index 77e3cb2962b..902e88527fc 100644
--- a/fs/omfs/file.c
+++ b/fs/omfs/file.c
@@ -306,6 +306,16 @@ omfs_writepages(struct address_space *mapping, struct writeback_control *wbc)
return mpage_writepages(mapping, wbc, omfs_get_block);
}
+static void omfs_write_failed(struct address_space *mapping, loff_t to)
+{
+ struct inode *inode = mapping->host;
+
+ if (to > inode->i_size) {
+ truncate_pagecache(inode, inode->i_size);
+ omfs_truncate(inode);
+ }
+}
+
static int omfs_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata)
@@ -314,11 +324,8 @@ static int omfs_write_begin(struct file *file, struct address_space *mapping,
ret = block_write_begin(mapping, pos, len, flags, pagep,
omfs_get_block);
- if (unlikely(ret)) {
- loff_t isize = mapping->host->i_size;
- if (pos + len > isize)
- vmtruncate(mapping->host, isize);
- }
+ if (unlikely(ret))
+ omfs_write_failed(mapping, pos + len);
return ret;
}
@@ -330,10 +337,10 @@ static sector_t omfs_bmap(struct address_space *mapping, sector_t block)
const struct file_operations omfs_file_operations = {
.llseek = generic_file_llseek,
- .read = do_sync_read,
- .write = do_sync_write,
- .aio_read = generic_file_aio_read,
- .aio_write = generic_file_aio_write,
+ .read = new_sync_read,
+ .write = new_sync_write,
+ .read_iter = generic_file_read_iter,
+ .write_iter = generic_file_write_iter,
.mmap = generic_file_mmap,
.fsync = generic_file_fsync,
.splice_read = generic_file_splice_read,
@@ -350,9 +357,11 @@ static int omfs_setattr(struct dentry *dentry, struct iattr *attr)
if ((attr->ia_valid & ATTR_SIZE) &&
attr->ia_size != i_size_read(inode)) {
- error = vmtruncate(inode, attr->ia_size);
+ error = inode_newsize_ok(inode, attr->ia_size);
if (error)
return error;
+ truncate_setsize(inode, attr->ia_size);
+ omfs_truncate(inode);
}
setattr_copy(inode, attr);
@@ -362,7 +371,6 @@ static int omfs_setattr(struct dentry *dentry, struct iattr *attr)
const struct inode_operations omfs_file_inops = {
.setattr = omfs_setattr,
- .truncate = omfs_truncate
};
const struct address_space_operations omfs_aops = {
diff --git a/fs/omfs/inode.c b/fs/omfs/inode.c
index 25d715c7c87..ec58c765918 100644
--- a/fs/omfs/inode.c
+++ b/fs/omfs/inode.c
@@ -183,7 +183,7 @@ int omfs_sync_inode(struct inode *inode)
*/
static void omfs_evict_inode(struct inode *inode)
{
- truncate_inode_pages(&inode->i_data, 0);
+ truncate_inode_pages_final(&inode->i_data);
clear_inode(inode);
if (inode->i_nlink)
@@ -572,6 +572,7 @@ static struct file_system_type omfs_fs_type = {
.kill_sb = kill_block_super,
.fs_flags = FS_REQUIRES_DEV,
};
+MODULE_ALIAS_FS("omfs");
static int __init init_omfs_fs(void)
{