Commit 1074fc75 authored by Nick Piggin's avatar Nick Piggin Committed by James Toy

Note I wasn't able to test jfs because the kernel wasn't mounting the

product of my mkfs.jfs for some reason.
Signed-off-by: default avatarNick Piggin <npiggin@suse.de>
Cc: Dave Kleikamp <shaggy@linux.vnet.ibm.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Jan Kara <jack@suse.cz>
Cc: Chris Mason <chris.mason@oracle.com>
Cc: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
Cc: Hugh Dickins <hugh.dickins@tiscali.co.uk>
Cc: Miklos Szeredi <miklos@szeredi.hu>
Cc: Trond Myklebust <trond.myklebust@fys.uio.no>
Cc: Steven French <sfrench@us.ibm.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
parent 4820f19a
......@@ -216,20 +216,14 @@ int jfs_setattr(struct dentry *dentry, struct iattr *iattr)
struct inode *inode = dentry->d_inode;
int rc;
rc = inode_change_ok(inode, iattr);
rc = simple_setattr(dentry, iattr);
if (rc)
return rc;
if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) ||
(iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) {
if (vfs_dq_transfer(inode, iattr))
return -EDQUOT;
}
rc = inode_setattr(inode, iattr);
if (!rc && (iattr->ia_valid & ATTR_MODE))
rc = jfs_acl_chmod(inode);
mark_inode_dirty(inode);
return rc;
}
......@@ -89,7 +89,7 @@ static int jfs_release(struct inode *inode, struct file *file)
}
const struct inode_operations jfs_file_inode_operations = {
.truncate = jfs_truncate,
.new_truncate = 1,
.setxattr = jfs_setxattr,
.getxattr = jfs_getxattr,
.listxattr = jfs_listxattr,
......
......@@ -297,8 +297,33 @@ static int jfs_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata)
{
return nobh_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
int ret;
ret = nobh_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
jfs_get_block);
if (ret < 0) {
struct inode *inode = mapping->host;
loff_t isize = inode->i_size;
if (pos + len > isize)
jfs_truncate_blocks(inode, isize);
}
return ret;
}
static int jfs_write_end(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned copied,
struct page *page, void *fsdata)
{
int ret;
ret = nobh_write_end(file, mapping, pos, len, copied, page, fsdata);
if (ret < len) {
struct inode *inode = mapping->host;
loff_t isize = inode->i_size;
if (pos + len > isize)
jfs_truncate_blocks(inode, isize);
}
return ret;
}
static sector_t jfs_bmap(struct address_space *mapping, sector_t block)
......@@ -311,9 +336,13 @@ static ssize_t jfs_direct_IO(int rw, struct kiocb *iocb,
{
struct file *file = iocb->ki_filp;
struct inode *inode = file->f_mapping->host;
ssize_t ret;
return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
ret = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
offset, nr_segs, jfs_get_block, NULL);
if (ret < 0)
jfs_truncate_blocks(inode, inode->i_size);
return ret;
}
const struct address_space_operations jfs_aops = {
......@@ -323,16 +352,16 @@ const struct address_space_operations jfs_aops = {
.writepages = jfs_writepages,
.sync_page = block_sync_page,
.write_begin = jfs_write_begin,
.write_end = nobh_write_end,
.write_end = jfs_write_end,
.bmap = jfs_bmap,
.direct_IO = jfs_direct_IO,
};
/*
* Guts of jfs_truncate. Called with locks already held. Can be called
* Guts of jfs_truncate_blocks. Called with locks already held. Can be called
* with directory for truncating directory index table.
*/
void jfs_truncate_nolock(struct inode *ip, loff_t length)
void jfs_truncate_blocks_nolock(struct inode *ip, loff_t length)
{
loff_t newsize;
tid_t tid;
......@@ -372,13 +401,20 @@ void jfs_truncate_nolock(struct inode *ip, loff_t length)
} while (newsize > length); /* Truncate isn't always atomic */
}
void jfs_truncate(struct inode *ip)
void jfs_truncate_blocks(struct inode *ip, loff_t offset)
{
jfs_info("jfs_truncate: size = 0x%lx", (ulong) ip->i_size);
nobh_truncate_page(ip->i_mapping, ip->i_size, jfs_get_block);
jfs_info("jfs_truncate: size = 0x%lx", (ulong) offset);
IWRITE_LOCK(ip, RDWRLOCK_NORMAL);
jfs_truncate_nolock(ip, ip->i_size);
jfs_truncate_blocks_nolock(ip, offset);
IWRITE_UNLOCK(ip);
}
void jfs_setsize(struct inode *ip, loff_t offset)
{
simple_setsize(ip, offset);
nobh_truncate_page(ip->i_mapping, offset, jfs_get_block);
jfs_truncate_blocks(ip, offset);
}
......@@ -29,8 +29,9 @@ extern int jfs_commit_inode(struct inode *, int);
extern int jfs_write_inode(struct inode*, int);
extern void jfs_delete_inode(struct inode *);
extern void jfs_dirty_inode(struct inode *);
extern void jfs_truncate(struct inode *);
extern void jfs_truncate_nolock(struct inode *, loff_t);
extern void jfs_truncate_blocks(struct inode *, loff_t);
extern void jfs_truncate_blocks_nolock(struct inode *, loff_t);
extern void jfs_setsize(struct inode *, loff_t);
extern void jfs_free_zero_link(struct inode *);
extern struct dentry *jfs_get_parent(struct dentry *dentry);
extern void jfs_get_inode_flags(struct jfs_inode_info *);
......
......@@ -3132,7 +3132,7 @@ void xtInitRoot(tid_t tid, struct inode *ip)
* note:
* PWMAP:
* 1. truncate (non-COMMIT_NOLINK file)
* by jfs_truncate() or jfs_open(O_TRUNC):
* by jfs_setsize() or jfs_open(O_TRUNC):
* xtree is updated;
* 2. truncate index table of directory when last entry removed
* map update via tlock at commit time;
......
......@@ -435,7 +435,7 @@ static int jfs_rmdir(struct inode *dip, struct dentry *dentry)
*/
if (test_cflag(COMMIT_Stale, dip)) {
if (dip->i_size > 1)
jfs_truncate_nolock(dip, 0);
jfs_truncate_blocks_nolock(dip, 0);
clear_cflag(COMMIT_Stale, dip);
}
......@@ -586,7 +586,7 @@ static int jfs_unlink(struct inode *dip, struct dentry *dentry)
*/
if (test_cflag(COMMIT_Stale, dip)) {
if (dip->i_size > 1)
jfs_truncate_nolock(dip, 0);
jfs_truncate_blocks_nolock(dip, 0);
clear_cflag(COMMIT_Stale, dip);
}
......@@ -1327,7 +1327,7 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
*/
if (test_cflag(COMMIT_Stale, old_dir)) {
if (old_dir->i_size > 1)
jfs_truncate_nolock(old_dir, 0);
jfs_truncate_blocks_nolock(old_dir, 0);
clear_cflag(COMMIT_Stale, old_dir);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment