diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ext2/balloc.c | 1 | ||||
-rw-r--r-- | fs/ext2/ialloc.c | 1 | ||||
-rw-r--r-- | fs/ext2/super.c | 41 | ||||
-rw-r--r-- | fs/ext3/inode.c | 2 | ||||
-rw-r--r-- | fs/ext3/super.c | 42 | ||||
-rw-r--r-- | fs/jffs2/nodelist.c | 6 | ||||
-rw-r--r-- | fs/jffs2/nodelist.h | 1 | ||||
-rw-r--r-- | fs/jffs2/summary.c | 5 | ||||
-rw-r--r-- | fs/jffs2/xattr.c | 1 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 6 | ||||
-rw-r--r-- | fs/nfs/read.c | 6 | ||||
-rw-r--r-- | fs/nfs/write.c | 4 |
12 files changed, 101 insertions, 15 deletions
diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c index d487043..b1981d0 100644 --- a/fs/ext2/balloc.c +++ b/fs/ext2/balloc.c @@ -539,7 +539,6 @@ unsigned long ext2_count_free (struct buffer_head * map, unsigned int numchars) #endif /* EXT2FS_DEBUG */ -/* Superblock must be locked */ unsigned long ext2_count_free_blocks (struct super_block * sb) { struct ext2_group_desc * desc; diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c index de85c61..695f69c 100644 --- a/fs/ext2/ialloc.c +++ b/fs/ext2/ialloc.c @@ -637,7 +637,6 @@ fail: return ERR_PTR(err); } -/* Superblock must be locked */ unsigned long ext2_count_free_inodes (struct super_block * sb) { struct ext2_group_desc *desc; diff --git a/fs/ext2/super.c b/fs/ext2/super.c index 681dea8..4286ff6 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c @@ -251,6 +251,44 @@ static struct super_operations ext2_sops = { #endif }; +static struct dentry *ext2_get_dentry(struct super_block *sb, void *vobjp) +{ + __u32 *objp = vobjp; + unsigned long ino = objp[0]; + __u32 generation = objp[1]; + struct inode *inode; + struct dentry *result; + + if (ino < EXT2_FIRST_INO(sb) && ino != EXT2_ROOT_INO) + return ERR_PTR(-ESTALE); + if (ino > le32_to_cpu(EXT2_SB(sb)->s_es->s_inodes_count)) + return ERR_PTR(-ESTALE); + + /* iget isn't really right if the inode is currently unallocated!! + * ext2_read_inode currently does appropriate checks, but + * it might be "neater" to call ext2_get_inode first and check + * if the inode is valid..... + */ + inode = iget(sb, ino); + if (inode == NULL) + return ERR_PTR(-ENOMEM); + if (is_bad_inode(inode) || + (generation && inode->i_generation != generation)) { + /* we didn't find the right inode.. */ + iput(inode); + return ERR_PTR(-ESTALE); + } + /* now to find a dentry. + * If possible, get a well-connected one + */ + result = d_alloc_anon(inode); + if (!result) { + iput(inode); + return ERR_PTR(-ENOMEM); + } + return result; +} + /* Yes, most of these are left as NULL!! * A NULL value implies the default, which works with ext2-like file * systems, but can be improved upon. @@ -258,6 +296,7 @@ static struct super_operations ext2_sops = { */ static struct export_operations ext2_export_ops = { .get_parent = ext2_get_parent, + .get_dentry = ext2_get_dentry, }; static unsigned long get_sb_block(void **data) @@ -1044,7 +1083,6 @@ static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf) unsigned long overhead; int i; - lock_super(sb); if (test_opt (sb, MINIX_DF)) overhead = 0; else { @@ -1085,7 +1123,6 @@ static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf) buf->f_files = le32_to_cpu(sbi->s_es->s_inodes_count); buf->f_ffree = ext2_count_free_inodes (sb); buf->f_namelen = EXT2_NAME_LEN; - unlock_super(sb); return 0; } diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index 0f0b1ea..84be02e 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c @@ -925,7 +925,7 @@ int ext3_get_blocks_handle(handle_t *handle, struct inode *inode, set_buffer_new(bh_result); got_it: map_bh(bh_result, inode->i_sb, le32_to_cpu(chain[depth-1].key)); - if (blocks_to_boundary == 0) + if (count > blocks_to_boundary) set_buffer_boundary(bh_result); err = count; /* Clean up and exit */ diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 813d589..3559086 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c @@ -554,6 +554,47 @@ static int ext3_show_options(struct seq_file *seq, struct vfsmount *vfs) return 0; } + +static struct dentry *ext3_get_dentry(struct super_block *sb, void *vobjp) +{ + __u32 *objp = vobjp; + unsigned long ino = objp[0]; + __u32 generation = objp[1]; + struct inode *inode; + struct dentry *result; + + if (ino < EXT3_FIRST_INO(sb) && ino != EXT3_ROOT_INO) + return ERR_PTR(-ESTALE); + if (ino > le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count)) + return ERR_PTR(-ESTALE); + + /* iget isn't really right if the inode is currently unallocated!! + * + * ext3_read_inode will return a bad_inode if the inode had been + * deleted, so we should be safe. + * + * Currently we don't know the generation for parent directory, so + * a generation of 0 means "accept any" + */ + inode = iget(sb, ino); + if (inode == NULL) + return ERR_PTR(-ENOMEM); + if (is_bad_inode(inode) || + (generation && inode->i_generation != generation)) { + iput(inode); + return ERR_PTR(-ESTALE); + } + /* now to find a dentry. + * If possible, get a well-connected one + */ + result = d_alloc_anon(inode); + if (!result) { + iput(inode); + return ERR_PTR(-ENOMEM); + } + return result; +} + #ifdef CONFIG_QUOTA #define QTYPE2NAME(t) ((t)==USRQUOTA?"user":"group") #define QTYPE2MOPT(on, t) ((t)==USRQUOTA?((on)##USRJQUOTA):((on)##GRPJQUOTA)) @@ -622,6 +663,7 @@ static struct super_operations ext3_sops = { static struct export_operations ext3_export_ops = { .get_parent = ext3_get_parent, + .get_dentry = ext3_get_dentry, }; enum { diff --git a/fs/jffs2/nodelist.c b/fs/jffs2/nodelist.c index 7675b33..5a6b4d6 100644 --- a/fs/jffs2/nodelist.c +++ b/fs/jffs2/nodelist.c @@ -21,6 +21,9 @@ #include <linux/pagemap.h> #include "nodelist.h" +static void jffs2_obsolete_node_frag(struct jffs2_sb_info *c, + struct jffs2_node_frag *this); + void jffs2_add_fd_to_list(struct jffs2_sb_info *c, struct jffs2_full_dirent *new, struct jffs2_full_dirent **list) { struct jffs2_full_dirent **prev = list; @@ -87,7 +90,8 @@ void jffs2_truncate_fragtree(struct jffs2_sb_info *c, struct rb_root *list, uint } } -void jffs2_obsolete_node_frag(struct jffs2_sb_info *c, struct jffs2_node_frag *this) +static void jffs2_obsolete_node_frag(struct jffs2_sb_info *c, + struct jffs2_node_frag *this) { if (this->node) { this->node->frags--; diff --git a/fs/jffs2/nodelist.h b/fs/jffs2/nodelist.h index cae92c1..0ddfd70 100644 --- a/fs/jffs2/nodelist.h +++ b/fs/jffs2/nodelist.h @@ -334,7 +334,6 @@ void jffs2_kill_fragtree(struct rb_root *root, struct jffs2_sb_info *c_delete); struct rb_node *rb_next(struct rb_node *); struct rb_node *rb_prev(struct rb_node *); void rb_replace_node(struct rb_node *victim, struct rb_node *new, struct rb_root *root); -void jffs2_obsolete_node_frag(struct jffs2_sb_info *c, struct jffs2_node_frag *this); int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_full_dnode *fn); void jffs2_truncate_fragtree (struct jffs2_sb_info *c, struct rb_root *list, uint32_t size); int jffs2_add_older_frag_to_fragtree(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_tmp_dnode_info *tn); diff --git a/fs/jffs2/summary.c b/fs/jffs2/summary.c index c19bd47..e52cef5 100644 --- a/fs/jffs2/summary.c +++ b/fs/jffs2/summary.c @@ -252,6 +252,11 @@ int jffs2_sum_add_kvec(struct jffs2_sb_info *c, const struct kvec *invecs, union jffs2_node_union *node; struct jffs2_eraseblock *jeb; + if (c->summary->sum_size == JFFS2_SUMMARY_NOSUM_SIZE) { + dbg_summary("Summary is disabled for this jeb! Skipping summary info!\n"); + return 0; + } + node = invecs[0].iov_base; jeb = &c->blocks[ofs / c->sector_size]; ofs -= jeb->offset; diff --git a/fs/jffs2/xattr.c b/fs/jffs2/xattr.c index 25bc1ae..4da09ce 100644 --- a/fs/jffs2/xattr.c +++ b/fs/jffs2/xattr.c @@ -1215,7 +1215,6 @@ int jffs2_garbage_collect_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xatt rc = jffs2_reserve_space_gc(c, totlen, &length, JFFS2_SUMMARY_XATTR_SIZE); if (rc) { JFFS2_WARNING("jffs2_reserve_space_gc()=%d, request=%u\n", rc, totlen); - rc = rc ? rc : -EBADFD; goto out; } rc = save_xattr_datum(c, xd); diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 153898e..b14145b 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -970,7 +970,7 @@ static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, int flags, st status = -ENOMEM; opendata = nfs4_opendata_alloc(dentry, sp, flags, sattr); if (opendata == NULL) - goto err_put_state_owner; + goto err_release_rwsem; status = _nfs4_proc_open(opendata); if (status != 0) @@ -989,11 +989,11 @@ static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, int flags, st return 0; err_opendata_free: nfs4_opendata_free(opendata); +err_release_rwsem: + up_read(&clp->cl_sem); err_put_state_owner: nfs4_put_state_owner(sp); out_err: - /* Note: clp->cl_sem must be released before nfs4_put_open_state()! */ - up_read(&clp->cl_sem); *res = NULL; return status; } diff --git a/fs/nfs/read.c b/fs/nfs/read.c index 7a9ee00..f0aff82 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c @@ -204,9 +204,11 @@ static int nfs_readpage_sync(struct nfs_open_context *ctx, struct inode *inode, NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATIME; spin_unlock(&inode->i_lock); - nfs_readpage_truncate_uninitialised_page(rdata); - if (rdata->res.eof || rdata->res.count == rdata->args.count) + if (rdata->res.eof || rdata->res.count == rdata->args.count) { SetPageUptodate(page); + if (rdata->res.eof && count != 0) + memclear_highpage_flush(page, rdata->args.pgbase, count); + } result = 0; io_error: diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 8ab3cf1..7084ac9 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -590,8 +590,8 @@ static void nfs_cancel_commit_list(struct list_head *head) req = nfs_list_entry(head->next); nfs_list_remove_request(req); nfs_inode_remove_request(req); - nfs_clear_page_writeback(req); dec_zone_page_state(req->wb_page, NR_UNSTABLE_NFS); + nfs_clear_page_writeback(req); } } @@ -1386,8 +1386,8 @@ nfs_commit_list(struct inode *inode, struct list_head *head, int how) req = nfs_list_entry(head->next); nfs_list_remove_request(req); nfs_mark_request_commit(req); - nfs_clear_page_writeback(req); dec_zone_page_state(req->wb_page, NR_UNSTABLE_NFS); + nfs_clear_page_writeback(req); } return -ENOMEM; } |