Commit eb3a6d15 authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[PATCH] hpfs: new/read/write_inode() cleanups

	1) common initialization for all paths in hpfs_read_inode() taken into
a separate helper (hpfs_init_inode())
	2) hpfs mkdir(),create(),mknod() and symlink() do not bother with
iget() anymore - they call new_inode(), do initializations and insert new
inode into icache.  Handling of OOM failures cleaned up - if we can't
allocate in-core inode, bail instead of corrupting the filesystem.
Allocating in-core inode early also avoids one of the deadlocks here
(hpfs_write_inode() from memory pressure by kmem_cache_alloc() could
deadlock on attempt to lock our directory).
	3) hpfs_write_inode() marks the inode dirty again in case if it
fails to iget() its parent directory.  Again, OOM could trigger fs corruption
here.
parent fde48def
...@@ -249,6 +249,7 @@ ssize_t hpfs_file_write(struct file *file, const char __user *buf, size_t count, ...@@ -249,6 +249,7 @@ ssize_t hpfs_file_write(struct file *file, const char __user *buf, size_t count,
/* inode.c */ /* inode.c */
void hpfs_init_inode(struct inode *);
void hpfs_read_inode(struct inode *); void hpfs_read_inode(struct inode *);
void hpfs_write_inode_ea(struct inode *, struct fnode *); void hpfs_write_inode_ea(struct inode *, struct fnode *);
void hpfs_write_inode(struct inode *); void hpfs_write_inode(struct inode *);
......
...@@ -57,14 +57,10 @@ struct address_space_operations hpfs_symlink_aops = { ...@@ -57,14 +57,10 @@ struct address_space_operations hpfs_symlink_aops = {
.readpage = hpfs_symlink_readpage .readpage = hpfs_symlink_readpage
}; };
void hpfs_read_inode(struct inode *i) void hpfs_init_inode(struct inode *i)
{ {
struct buffer_head *bh;
struct fnode *fnode;
struct super_block *sb = i->i_sb; struct super_block *sb = i->i_sb;
struct hpfs_inode_info *hpfs_inode = hpfs_i(i); struct hpfs_inode_info *hpfs_inode = hpfs_i(i);
unsigned char *ea;
int ea_size;
i->i_uid = hpfs_sb(sb)->sb_uid; i->i_uid = hpfs_sb(sb)->sb_uid;
i->i_gid = hpfs_sb(sb)->sb_gid; i->i_gid = hpfs_sb(sb)->sb_gid;
...@@ -91,6 +87,18 @@ void hpfs_read_inode(struct inode *i) ...@@ -91,6 +87,18 @@ void hpfs_read_inode(struct inode *i)
i->i_ctime.tv_sec = i->i_ctime.tv_nsec = 0; i->i_ctime.tv_sec = i->i_ctime.tv_nsec = 0;
i->i_mtime.tv_sec = i->i_mtime.tv_nsec = 0; i->i_mtime.tv_sec = i->i_mtime.tv_nsec = 0;
i->i_atime.tv_sec = i->i_atime.tv_nsec = 0; i->i_atime.tv_sec = i->i_atime.tv_nsec = 0;
}
void hpfs_read_inode(struct inode *i)
{
struct buffer_head *bh;
struct fnode *fnode;
struct super_block *sb = i->i_sb;
struct hpfs_inode_info *hpfs_inode = hpfs_i(i);
unsigned char *ea;
int ea_size;
hpfs_init_inode(i);
if (!hpfs_sb(i->i_sb)->sb_rd_inode) if (!hpfs_sb(i->i_sb)->sb_rd_inode)
hpfs_error(i->i_sb, "read_inode: sb_rd_inode == 0"); hpfs_error(i->i_sb, "read_inode: sb_rd_inode == 0");
...@@ -240,14 +248,19 @@ void hpfs_write_inode(struct inode *i) ...@@ -240,14 +248,19 @@ void hpfs_write_inode(struct inode *i)
kfree(hpfs_inode->i_rddir_off); kfree(hpfs_inode->i_rddir_off);
hpfs_inode->i_rddir_off = NULL; hpfs_inode->i_rddir_off = NULL;
} }
hpfs_inode->i_dirty = 0;
hpfs_lock_iget(i->i_sb, 1); hpfs_lock_iget(i->i_sb, 1);
parent = iget(i->i_sb, hpfs_inode->i_parent_dir); parent = iget(i->i_sb, hpfs_inode->i_parent_dir);
hpfs_unlock_iget(i->i_sb); if (parent) {
hpfs_lock_inode(parent); hpfs_unlock_iget(i->i_sb);
hpfs_write_inode_nolock(i); hpfs_inode->i_dirty = 0;
hpfs_unlock_inode(parent); hpfs_lock_inode(parent);
iput(parent); hpfs_write_inode_nolock(i);
hpfs_unlock_inode(parent);
iput(parent);
} else {
hpfs_unlock_iget(i->i_sb);
mark_inode_dirty(i);
}
} }
void hpfs_write_inode_nolock(struct inode *i) void hpfs_write_inode_nolock(struct inode *i)
......
This diff is collapsed.
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