diff options
Diffstat (limited to 'fs/ext3')
-rw-r--r-- | fs/ext3/acl.c | 2 | ||||
-rw-r--r-- | fs/ext3/acl.h | 2 | ||||
-rw-r--r-- | fs/ext3/dir.c | 14 | ||||
-rw-r--r-- | fs/ext3/ialloc.c | 9 | ||||
-rw-r--r-- | fs/ext3/inode.c | 113 | ||||
-rw-r--r-- | fs/ext3/namei.c | 26 | ||||
-rw-r--r-- | fs/ext3/super.c | 83 | ||||
-rw-r--r-- | fs/ext3/xattr_security.c | 2 | ||||
-rw-r--r-- | fs/ext3/xattr_trusted.c | 4 | ||||
-rw-r--r-- | fs/ext3/xattr_user.c | 4 |
10 files changed, 165 insertions, 94 deletions
diff --git a/fs/ext3/acl.c b/fs/ext3/acl.c index a754d1848173..b60bb241880c 100644 --- a/fs/ext3/acl.c +++ b/fs/ext3/acl.c | |||
@@ -299,7 +299,7 @@ ext3_check_acl(struct inode *inode, int mask) | |||
299 | } | 299 | } |
300 | 300 | ||
301 | int | 301 | int |
302 | ext3_permission(struct inode *inode, int mask, struct nameidata *nd) | 302 | ext3_permission(struct inode *inode, int mask) |
303 | { | 303 | { |
304 | return generic_permission(inode, mask, ext3_check_acl); | 304 | return generic_permission(inode, mask, ext3_check_acl); |
305 | } | 305 | } |
diff --git a/fs/ext3/acl.h b/fs/ext3/acl.h index 0d1e6279cbfd..42da16b8cac0 100644 --- a/fs/ext3/acl.h +++ b/fs/ext3/acl.h | |||
@@ -58,7 +58,7 @@ static inline int ext3_acl_count(size_t size) | |||
58 | #define EXT3_ACL_NOT_CACHED ((void *)-1) | 58 | #define EXT3_ACL_NOT_CACHED ((void *)-1) |
59 | 59 | ||
60 | /* acl.c */ | 60 | /* acl.c */ |
61 | extern int ext3_permission (struct inode *, int, struct nameidata *); | 61 | extern int ext3_permission (struct inode *, int); |
62 | extern int ext3_acl_chmod (struct inode *); | 62 | extern int ext3_acl_chmod (struct inode *); |
63 | extern int ext3_init_acl (handle_t *, struct inode *, struct inode *); | 63 | extern int ext3_init_acl (handle_t *, struct inode *, struct inode *); |
64 | 64 | ||
diff --git a/fs/ext3/dir.c b/fs/ext3/dir.c index 8ca3bfd72427..2eea96ec78ed 100644 --- a/fs/ext3/dir.c +++ b/fs/ext3/dir.c | |||
@@ -272,7 +272,7 @@ static void free_rb_tree_fname(struct rb_root *root) | |||
272 | 272 | ||
273 | while (n) { | 273 | while (n) { |
274 | /* Do the node's children first */ | 274 | /* Do the node's children first */ |
275 | if ((n)->rb_left) { | 275 | if (n->rb_left) { |
276 | n = n->rb_left; | 276 | n = n->rb_left; |
277 | continue; | 277 | continue; |
278 | } | 278 | } |
@@ -301,24 +301,18 @@ static void free_rb_tree_fname(struct rb_root *root) | |||
301 | parent->rb_right = NULL; | 301 | parent->rb_right = NULL; |
302 | n = parent; | 302 | n = parent; |
303 | } | 303 | } |
304 | root->rb_node = NULL; | ||
305 | } | 304 | } |
306 | 305 | ||
307 | 306 | ||
308 | static struct dir_private_info *create_dir_info(loff_t pos) | 307 | static struct dir_private_info *ext3_htree_create_dir_info(loff_t pos) |
309 | { | 308 | { |
310 | struct dir_private_info *p; | 309 | struct dir_private_info *p; |
311 | 310 | ||
312 | p = kmalloc(sizeof(struct dir_private_info), GFP_KERNEL); | 311 | p = kzalloc(sizeof(struct dir_private_info), GFP_KERNEL); |
313 | if (!p) | 312 | if (!p) |
314 | return NULL; | 313 | return NULL; |
315 | p->root.rb_node = NULL; | ||
316 | p->curr_node = NULL; | ||
317 | p->extra_fname = NULL; | ||
318 | p->last_pos = 0; | ||
319 | p->curr_hash = pos2maj_hash(pos); | 314 | p->curr_hash = pos2maj_hash(pos); |
320 | p->curr_minor_hash = pos2min_hash(pos); | 315 | p->curr_minor_hash = pos2min_hash(pos); |
321 | p->next_hash = 0; | ||
322 | return p; | 316 | return p; |
323 | } | 317 | } |
324 | 318 | ||
@@ -433,7 +427,7 @@ static int ext3_dx_readdir(struct file * filp, | |||
433 | int ret; | 427 | int ret; |
434 | 428 | ||
435 | if (!info) { | 429 | if (!info) { |
436 | info = create_dir_info(filp->f_pos); | 430 | info = ext3_htree_create_dir_info(filp->f_pos); |
437 | if (!info) | 431 | if (!info) |
438 | return -ENOMEM; | 432 | return -ENOMEM; |
439 | filp->private_data = info; | 433 | filp->private_data = info; |
diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c index 77126821b2e9..47b678d73e7a 100644 --- a/fs/ext3/ialloc.c +++ b/fs/ext3/ialloc.c | |||
@@ -669,6 +669,14 @@ struct inode *ext3_orphan_get(struct super_block *sb, unsigned long ino) | |||
669 | if (IS_ERR(inode)) | 669 | if (IS_ERR(inode)) |
670 | goto iget_failed; | 670 | goto iget_failed; |
671 | 671 | ||
672 | /* | ||
673 | * If the orphans has i_nlinks > 0 then it should be able to be | ||
674 | * truncated, otherwise it won't be removed from the orphan list | ||
675 | * during processing and an infinite loop will result. | ||
676 | */ | ||
677 | if (inode->i_nlink && !ext3_can_truncate(inode)) | ||
678 | goto bad_orphan; | ||
679 | |||
672 | if (NEXT_ORPHAN(inode) > max_ino) | 680 | if (NEXT_ORPHAN(inode) > max_ino) |
673 | goto bad_orphan; | 681 | goto bad_orphan; |
674 | brelse(bitmap_bh); | 682 | brelse(bitmap_bh); |
@@ -690,6 +698,7 @@ bad_orphan: | |||
690 | printk(KERN_NOTICE "NEXT_ORPHAN(inode)=%u\n", | 698 | printk(KERN_NOTICE "NEXT_ORPHAN(inode)=%u\n", |
691 | NEXT_ORPHAN(inode)); | 699 | NEXT_ORPHAN(inode)); |
692 | printk(KERN_NOTICE "max_ino=%lu\n", max_ino); | 700 | printk(KERN_NOTICE "max_ino=%lu\n", max_ino); |
701 | printk(KERN_NOTICE "i_nlink=%u\n", inode->i_nlink); | ||
693 | /* Avoid freeing blocks if we got a bad deleted inode */ | 702 | /* Avoid freeing blocks if we got a bad deleted inode */ |
694 | if (inode->i_nlink == 0) | 703 | if (inode->i_nlink == 0) |
695 | inode->i_blocks = 0; | 704 | inode->i_blocks = 0; |
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index 6ae4ecf3ce40..507d8689b111 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c | |||
@@ -1767,44 +1767,47 @@ static int ext3_journalled_set_page_dirty(struct page *page) | |||
1767 | } | 1767 | } |
1768 | 1768 | ||
1769 | static const struct address_space_operations ext3_ordered_aops = { | 1769 | static const struct address_space_operations ext3_ordered_aops = { |
1770 | .readpage = ext3_readpage, | 1770 | .readpage = ext3_readpage, |
1771 | .readpages = ext3_readpages, | 1771 | .readpages = ext3_readpages, |
1772 | .writepage = ext3_ordered_writepage, | 1772 | .writepage = ext3_ordered_writepage, |
1773 | .sync_page = block_sync_page, | 1773 | .sync_page = block_sync_page, |
1774 | .write_begin = ext3_write_begin, | 1774 | .write_begin = ext3_write_begin, |
1775 | .write_end = ext3_ordered_write_end, | 1775 | .write_end = ext3_ordered_write_end, |
1776 | .bmap = ext3_bmap, | 1776 | .bmap = ext3_bmap, |
1777 | .invalidatepage = ext3_invalidatepage, | 1777 | .invalidatepage = ext3_invalidatepage, |
1778 | .releasepage = ext3_releasepage, | 1778 | .releasepage = ext3_releasepage, |
1779 | .direct_IO = ext3_direct_IO, | 1779 | .direct_IO = ext3_direct_IO, |
1780 | .migratepage = buffer_migrate_page, | 1780 | .migratepage = buffer_migrate_page, |
1781 | .is_partially_uptodate = block_is_partially_uptodate, | ||
1781 | }; | 1782 | }; |
1782 | 1783 | ||
1783 | static const struct address_space_operations ext3_writeback_aops = { | 1784 | static const struct address_space_operations ext3_writeback_aops = { |
1784 | .readpage = ext3_readpage, | 1785 | .readpage = ext3_readpage, |
1785 | .readpages = ext3_readpages, | 1786 | .readpages = ext3_readpages, |
1786 | .writepage = ext3_writeback_writepage, | 1787 | .writepage = ext3_writeback_writepage, |
1787 | .sync_page = block_sync_page, | 1788 | .sync_page = block_sync_page, |
1788 | .write_begin = ext3_write_begin, | 1789 | .write_begin = ext3_write_begin, |
1789 | .write_end = ext3_writeback_write_end, | 1790 | .write_end = ext3_writeback_write_end, |
1790 | .bmap = ext3_bmap, | 1791 | .bmap = ext3_bmap, |
1791 | .invalidatepage = ext3_invalidatepage, | 1792 | .invalidatepage = ext3_invalidatepage, |
1792 | .releasepage = ext3_releasepage, | 1793 | .releasepage = ext3_releasepage, |
1793 | .direct_IO = ext3_direct_IO, | 1794 | .direct_IO = ext3_direct_IO, |
1794 | .migratepage = buffer_migrate_page, | 1795 | .migratepage = buffer_migrate_page, |
1796 | .is_partially_uptodate = block_is_partially_uptodate, | ||
1795 | }; | 1797 | }; |
1796 | 1798 | ||
1797 | static const struct address_space_operations ext3_journalled_aops = { | 1799 | static const struct address_space_operations ext3_journalled_aops = { |
1798 | .readpage = ext3_readpage, | 1800 | .readpage = ext3_readpage, |
1799 | .readpages = ext3_readpages, | 1801 | .readpages = ext3_readpages, |
1800 | .writepage = ext3_journalled_writepage, | 1802 | .writepage = ext3_journalled_writepage, |
1801 | .sync_page = block_sync_page, | 1803 | .sync_page = block_sync_page, |
1802 | .write_begin = ext3_write_begin, | 1804 | .write_begin = ext3_write_begin, |
1803 | .write_end = ext3_journalled_write_end, | 1805 | .write_end = ext3_journalled_write_end, |
1804 | .set_page_dirty = ext3_journalled_set_page_dirty, | 1806 | .set_page_dirty = ext3_journalled_set_page_dirty, |
1805 | .bmap = ext3_bmap, | 1807 | .bmap = ext3_bmap, |
1806 | .invalidatepage = ext3_invalidatepage, | 1808 | .invalidatepage = ext3_invalidatepage, |
1807 | .releasepage = ext3_releasepage, | 1809 | .releasepage = ext3_releasepage, |
1810 | .is_partially_uptodate = block_is_partially_uptodate, | ||
1808 | }; | 1811 | }; |
1809 | 1812 | ||
1810 | void ext3_set_aops(struct inode *inode) | 1813 | void ext3_set_aops(struct inode *inode) |
@@ -2127,7 +2130,21 @@ static void ext3_free_data(handle_t *handle, struct inode *inode, | |||
2127 | 2130 | ||
2128 | if (this_bh) { | 2131 | if (this_bh) { |
2129 | BUFFER_TRACE(this_bh, "call ext3_journal_dirty_metadata"); | 2132 | BUFFER_TRACE(this_bh, "call ext3_journal_dirty_metadata"); |
2130 | ext3_journal_dirty_metadata(handle, this_bh); | 2133 | |
2134 | /* | ||
2135 | * The buffer head should have an attached journal head at this | ||
2136 | * point. However, if the data is corrupted and an indirect | ||
2137 | * block pointed to itself, it would have been detached when | ||
2138 | * the block was cleared. Check for this instead of OOPSing. | ||
2139 | */ | ||
2140 | if (bh2jh(this_bh)) | ||
2141 | ext3_journal_dirty_metadata(handle, this_bh); | ||
2142 | else | ||
2143 | ext3_error(inode->i_sb, "ext3_free_data", | ||
2144 | "circular indirect block detected, " | ||
2145 | "inode=%lu, block=%llu", | ||
2146 | inode->i_ino, | ||
2147 | (unsigned long long)this_bh->b_blocknr); | ||
2131 | } | 2148 | } |
2132 | } | 2149 | } |
2133 | 2150 | ||
@@ -2253,6 +2270,19 @@ static void ext3_free_branches(handle_t *handle, struct inode *inode, | |||
2253 | } | 2270 | } |
2254 | } | 2271 | } |
2255 | 2272 | ||
2273 | int ext3_can_truncate(struct inode *inode) | ||
2274 | { | ||
2275 | if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) | ||
2276 | return 0; | ||
2277 | if (S_ISREG(inode->i_mode)) | ||
2278 | return 1; | ||
2279 | if (S_ISDIR(inode->i_mode)) | ||
2280 | return 1; | ||
2281 | if (S_ISLNK(inode->i_mode)) | ||
2282 | return !ext3_inode_is_fast_symlink(inode); | ||
2283 | return 0; | ||
2284 | } | ||
2285 | |||
2256 | /* | 2286 | /* |
2257 | * ext3_truncate() | 2287 | * ext3_truncate() |
2258 | * | 2288 | * |
@@ -2297,12 +2327,7 @@ void ext3_truncate(struct inode *inode) | |||
2297 | unsigned blocksize = inode->i_sb->s_blocksize; | 2327 | unsigned blocksize = inode->i_sb->s_blocksize; |
2298 | struct page *page; | 2328 | struct page *page; |
2299 | 2329 | ||
2300 | if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || | 2330 | if (!ext3_can_truncate(inode)) |
2301 | S_ISLNK(inode->i_mode))) | ||
2302 | return; | ||
2303 | if (ext3_inode_is_fast_symlink(inode)) | ||
2304 | return; | ||
2305 | if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) | ||
2306 | return; | 2331 | return; |
2307 | 2332 | ||
2308 | /* | 2333 | /* |
@@ -2513,6 +2538,16 @@ static int __ext3_get_inode_loc(struct inode *inode, | |||
2513 | } | 2538 | } |
2514 | if (!buffer_uptodate(bh)) { | 2539 | if (!buffer_uptodate(bh)) { |
2515 | lock_buffer(bh); | 2540 | lock_buffer(bh); |
2541 | |||
2542 | /* | ||
2543 | * If the buffer has the write error flag, we have failed | ||
2544 | * to write out another inode in the same block. In this | ||
2545 | * case, we don't have to read the block because we may | ||
2546 | * read the old inode data successfully. | ||
2547 | */ | ||
2548 | if (buffer_write_io_error(bh) && !buffer_uptodate(bh)) | ||
2549 | set_buffer_uptodate(bh); | ||
2550 | |||
2516 | if (buffer_uptodate(bh)) { | 2551 | if (buffer_uptodate(bh)) { |
2517 | /* someone brought it uptodate while we waited */ | 2552 | /* someone brought it uptodate while we waited */ |
2518 | unlock_buffer(bh); | 2553 | unlock_buffer(bh); |
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index 0b8cf80154f1..de13e919cd81 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c | |||
@@ -240,13 +240,13 @@ static inline unsigned dx_root_limit (struct inode *dir, unsigned infosize) | |||
240 | { | 240 | { |
241 | unsigned entry_space = dir->i_sb->s_blocksize - EXT3_DIR_REC_LEN(1) - | 241 | unsigned entry_space = dir->i_sb->s_blocksize - EXT3_DIR_REC_LEN(1) - |
242 | EXT3_DIR_REC_LEN(2) - infosize; | 242 | EXT3_DIR_REC_LEN(2) - infosize; |
243 | return 0? 20: entry_space / sizeof(struct dx_entry); | 243 | return entry_space / sizeof(struct dx_entry); |
244 | } | 244 | } |
245 | 245 | ||
246 | static inline unsigned dx_node_limit (struct inode *dir) | 246 | static inline unsigned dx_node_limit (struct inode *dir) |
247 | { | 247 | { |
248 | unsigned entry_space = dir->i_sb->s_blocksize - EXT3_DIR_REC_LEN(0); | 248 | unsigned entry_space = dir->i_sb->s_blocksize - EXT3_DIR_REC_LEN(0); |
249 | return 0? 22: entry_space / sizeof(struct dx_entry); | 249 | return entry_space / sizeof(struct dx_entry); |
250 | } | 250 | } |
251 | 251 | ||
252 | /* | 252 | /* |
@@ -991,19 +991,21 @@ static struct buffer_head * ext3_dx_find_entry(struct dentry *dentry, | |||
991 | de = (struct ext3_dir_entry_2 *) bh->b_data; | 991 | de = (struct ext3_dir_entry_2 *) bh->b_data; |
992 | top = (struct ext3_dir_entry_2 *) ((char *) de + sb->s_blocksize - | 992 | top = (struct ext3_dir_entry_2 *) ((char *) de + sb->s_blocksize - |
993 | EXT3_DIR_REC_LEN(0)); | 993 | EXT3_DIR_REC_LEN(0)); |
994 | for (; de < top; de = ext3_next_entry(de)) | 994 | for (; de < top; de = ext3_next_entry(de)) { |
995 | if (ext3_match (namelen, name, de)) { | 995 | int off = (block << EXT3_BLOCK_SIZE_BITS(sb)) |
996 | if (!ext3_check_dir_entry("ext3_find_entry", | 996 | + ((char *) de - bh->b_data); |
997 | dir, de, bh, | 997 | |
998 | (block<<EXT3_BLOCK_SIZE_BITS(sb)) | 998 | if (!ext3_check_dir_entry(__func__, dir, de, bh, off)) { |
999 | +((char *)de - bh->b_data))) { | 999 | brelse(bh); |
1000 | brelse (bh); | ||
1001 | *err = ERR_BAD_DX_DIR; | 1000 | *err = ERR_BAD_DX_DIR; |
1002 | goto errout; | 1001 | goto errout; |
1003 | } | 1002 | } |
1004 | *res_dir = de; | 1003 | |
1005 | dx_release (frames); | 1004 | if (ext3_match(namelen, name, de)) { |
1006 | return bh; | 1005 | *res_dir = de; |
1006 | dx_release(frames); | ||
1007 | return bh; | ||
1008 | } | ||
1007 | } | 1009 | } |
1008 | brelse (bh); | 1010 | brelse (bh); |
1009 | /* Check to see if we should continue to search */ | 1011 | /* Check to see if we should continue to search */ |
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 2845425077e8..f38a5afc39a1 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
@@ -472,7 +472,7 @@ static void ext3_destroy_inode(struct inode *inode) | |||
472 | kmem_cache_free(ext3_inode_cachep, EXT3_I(inode)); | 472 | kmem_cache_free(ext3_inode_cachep, EXT3_I(inode)); |
473 | } | 473 | } |
474 | 474 | ||
475 | static void init_once(struct kmem_cache * cachep, void *foo) | 475 | static void init_once(void *foo) |
476 | { | 476 | { |
477 | struct ext3_inode_info *ei = (struct ext3_inode_info *) foo; | 477 | struct ext3_inode_info *ei = (struct ext3_inode_info *) foo; |
478 | 478 | ||
@@ -842,7 +842,7 @@ static int parse_options (char *options, struct super_block *sb, | |||
842 | int data_opt = 0; | 842 | int data_opt = 0; |
843 | int option; | 843 | int option; |
844 | #ifdef CONFIG_QUOTA | 844 | #ifdef CONFIG_QUOTA |
845 | int qtype; | 845 | int qtype, qfmt; |
846 | char *qname; | 846 | char *qname; |
847 | #endif | 847 | #endif |
848 | 848 | ||
@@ -1018,9 +1018,11 @@ static int parse_options (char *options, struct super_block *sb, | |||
1018 | case Opt_grpjquota: | 1018 | case Opt_grpjquota: |
1019 | qtype = GRPQUOTA; | 1019 | qtype = GRPQUOTA; |
1020 | set_qf_name: | 1020 | set_qf_name: |
1021 | if (sb_any_quota_enabled(sb)) { | 1021 | if ((sb_any_quota_enabled(sb) || |
1022 | sb_any_quota_suspended(sb)) && | ||
1023 | !sbi->s_qf_names[qtype]) { | ||
1022 | printk(KERN_ERR | 1024 | printk(KERN_ERR |
1023 | "EXT3-fs: Cannot change journalled " | 1025 | "EXT3-fs: Cannot change journaled " |
1024 | "quota options when quota turned on.\n"); | 1026 | "quota options when quota turned on.\n"); |
1025 | return 0; | 1027 | return 0; |
1026 | } | 1028 | } |
@@ -1056,9 +1058,11 @@ set_qf_name: | |||
1056 | case Opt_offgrpjquota: | 1058 | case Opt_offgrpjquota: |
1057 | qtype = GRPQUOTA; | 1059 | qtype = GRPQUOTA; |
1058 | clear_qf_name: | 1060 | clear_qf_name: |
1059 | if (sb_any_quota_enabled(sb)) { | 1061 | if ((sb_any_quota_enabled(sb) || |
1062 | sb_any_quota_suspended(sb)) && | ||
1063 | sbi->s_qf_names[qtype]) { | ||
1060 | printk(KERN_ERR "EXT3-fs: Cannot change " | 1064 | printk(KERN_ERR "EXT3-fs: Cannot change " |
1061 | "journalled quota options when " | 1065 | "journaled quota options when " |
1062 | "quota turned on.\n"); | 1066 | "quota turned on.\n"); |
1063 | return 0; | 1067 | return 0; |
1064 | } | 1068 | } |
@@ -1069,10 +1073,20 @@ clear_qf_name: | |||
1069 | sbi->s_qf_names[qtype] = NULL; | 1073 | sbi->s_qf_names[qtype] = NULL; |
1070 | break; | 1074 | break; |
1071 | case Opt_jqfmt_vfsold: | 1075 | case Opt_jqfmt_vfsold: |
1072 | sbi->s_jquota_fmt = QFMT_VFS_OLD; | 1076 | qfmt = QFMT_VFS_OLD; |
1073 | break; | 1077 | goto set_qf_format; |
1074 | case Opt_jqfmt_vfsv0: | 1078 | case Opt_jqfmt_vfsv0: |
1075 | sbi->s_jquota_fmt = QFMT_VFS_V0; | 1079 | qfmt = QFMT_VFS_V0; |
1080 | set_qf_format: | ||
1081 | if ((sb_any_quota_enabled(sb) || | ||
1082 | sb_any_quota_suspended(sb)) && | ||
1083 | sbi->s_jquota_fmt != qfmt) { | ||
1084 | printk(KERN_ERR "EXT3-fs: Cannot change " | ||
1085 | "journaled quota options when " | ||
1086 | "quota turned on.\n"); | ||
1087 | return 0; | ||
1088 | } | ||
1089 | sbi->s_jquota_fmt = qfmt; | ||
1076 | break; | 1090 | break; |
1077 | case Opt_quota: | 1091 | case Opt_quota: |
1078 | case Opt_usrquota: | 1092 | case Opt_usrquota: |
@@ -1084,7 +1098,8 @@ clear_qf_name: | |||
1084 | set_opt(sbi->s_mount_opt, GRPQUOTA); | 1098 | set_opt(sbi->s_mount_opt, GRPQUOTA); |
1085 | break; | 1099 | break; |
1086 | case Opt_noquota: | 1100 | case Opt_noquota: |
1087 | if (sb_any_quota_enabled(sb)) { | 1101 | if (sb_any_quota_enabled(sb) || |
1102 | sb_any_quota_suspended(sb)) { | ||
1088 | printk(KERN_ERR "EXT3-fs: Cannot change quota " | 1103 | printk(KERN_ERR "EXT3-fs: Cannot change quota " |
1089 | "options when quota turned on.\n"); | 1104 | "options when quota turned on.\n"); |
1090 | return 0; | 1105 | return 0; |
@@ -1169,14 +1184,14 @@ clear_qf_name: | |||
1169 | } | 1184 | } |
1170 | 1185 | ||
1171 | if (!sbi->s_jquota_fmt) { | 1186 | if (!sbi->s_jquota_fmt) { |
1172 | printk(KERN_ERR "EXT3-fs: journalled quota format " | 1187 | printk(KERN_ERR "EXT3-fs: journaled quota format " |
1173 | "not specified.\n"); | 1188 | "not specified.\n"); |
1174 | return 0; | 1189 | return 0; |
1175 | } | 1190 | } |
1176 | } else { | 1191 | } else { |
1177 | if (sbi->s_jquota_fmt) { | 1192 | if (sbi->s_jquota_fmt) { |
1178 | printk(KERN_ERR "EXT3-fs: journalled quota format " | 1193 | printk(KERN_ERR "EXT3-fs: journaled quota format " |
1179 | "specified with no journalling " | 1194 | "specified with no journaling " |
1180 | "enabled.\n"); | 1195 | "enabled.\n"); |
1181 | return 0; | 1196 | return 0; |
1182 | } | 1197 | } |
@@ -1370,7 +1385,7 @@ static void ext3_orphan_cleanup (struct super_block * sb, | |||
1370 | int ret = ext3_quota_on_mount(sb, i); | 1385 | int ret = ext3_quota_on_mount(sb, i); |
1371 | if (ret < 0) | 1386 | if (ret < 0) |
1372 | printk(KERN_ERR | 1387 | printk(KERN_ERR |
1373 | "EXT3-fs: Cannot turn on journalled " | 1388 | "EXT3-fs: Cannot turn on journaled " |
1374 | "quota: error %d\n", ret); | 1389 | "quota: error %d\n", ret); |
1375 | } | 1390 | } |
1376 | } | 1391 | } |
@@ -2712,7 +2727,7 @@ static int ext3_release_dquot(struct dquot *dquot) | |||
2712 | 2727 | ||
2713 | static int ext3_mark_dquot_dirty(struct dquot *dquot) | 2728 | static int ext3_mark_dquot_dirty(struct dquot *dquot) |
2714 | { | 2729 | { |
2715 | /* Are we journalling quotas? */ | 2730 | /* Are we journaling quotas? */ |
2716 | if (EXT3_SB(dquot->dq_sb)->s_qf_names[USRQUOTA] || | 2731 | if (EXT3_SB(dquot->dq_sb)->s_qf_names[USRQUOTA] || |
2717 | EXT3_SB(dquot->dq_sb)->s_qf_names[GRPQUOTA]) { | 2732 | EXT3_SB(dquot->dq_sb)->s_qf_names[GRPQUOTA]) { |
2718 | dquot_mark_dquot_dirty(dquot); | 2733 | dquot_mark_dquot_dirty(dquot); |
@@ -2759,25 +2774,45 @@ static int ext3_quota_on(struct super_block *sb, int type, int format_id, | |||
2759 | 2774 | ||
2760 | if (!test_opt(sb, QUOTA)) | 2775 | if (!test_opt(sb, QUOTA)) |
2761 | return -EINVAL; | 2776 | return -EINVAL; |
2762 | /* Not journalling quota or remount? */ | 2777 | /* When remounting, no checks are needed and in fact, path is NULL */ |
2763 | if ((!EXT3_SB(sb)->s_qf_names[USRQUOTA] && | 2778 | if (remount) |
2764 | !EXT3_SB(sb)->s_qf_names[GRPQUOTA]) || remount) | ||
2765 | return vfs_quota_on(sb, type, format_id, path, remount); | 2779 | return vfs_quota_on(sb, type, format_id, path, remount); |
2780 | |||
2766 | err = path_lookup(path, LOOKUP_FOLLOW, &nd); | 2781 | err = path_lookup(path, LOOKUP_FOLLOW, &nd); |
2767 | if (err) | 2782 | if (err) |
2768 | return err; | 2783 | return err; |
2784 | |||
2769 | /* Quotafile not on the same filesystem? */ | 2785 | /* Quotafile not on the same filesystem? */ |
2770 | if (nd.path.mnt->mnt_sb != sb) { | 2786 | if (nd.path.mnt->mnt_sb != sb) { |
2771 | path_put(&nd.path); | 2787 | path_put(&nd.path); |
2772 | return -EXDEV; | 2788 | return -EXDEV; |
2773 | } | 2789 | } |
2774 | /* Quotafile not in fs root? */ | 2790 | /* Journaling quota? */ |
2775 | if (nd.path.dentry->d_parent->d_inode != sb->s_root->d_inode) | 2791 | if (EXT3_SB(sb)->s_qf_names[type]) { |
2776 | printk(KERN_WARNING | 2792 | /* Quotafile not of fs root? */ |
2777 | "EXT3-fs: Quota file not on filesystem root. " | 2793 | if (nd.path.dentry->d_parent->d_inode != sb->s_root->d_inode) |
2778 | "Journalled quota will not work.\n"); | 2794 | printk(KERN_WARNING |
2795 | "EXT3-fs: Quota file not on filesystem root. " | ||
2796 | "Journaled quota will not work.\n"); | ||
2797 | } | ||
2798 | |||
2799 | /* | ||
2800 | * When we journal data on quota file, we have to flush journal to see | ||
2801 | * all updates to the file when we bypass pagecache... | ||
2802 | */ | ||
2803 | if (ext3_should_journal_data(nd.path.dentry->d_inode)) { | ||
2804 | /* | ||
2805 | * We don't need to lock updates but journal_flush() could | ||
2806 | * otherwise be livelocked... | ||
2807 | */ | ||
2808 | journal_lock_updates(EXT3_SB(sb)->s_journal); | ||
2809 | journal_flush(EXT3_SB(sb)->s_journal); | ||
2810 | journal_unlock_updates(EXT3_SB(sb)->s_journal); | ||
2811 | } | ||
2812 | |||
2813 | err = vfs_quota_on_path(sb, type, format_id, &nd.path); | ||
2779 | path_put(&nd.path); | 2814 | path_put(&nd.path); |
2780 | return vfs_quota_on(sb, type, format_id, path, remount); | 2815 | return err; |
2781 | } | 2816 | } |
2782 | 2817 | ||
2783 | /* Read data from quotafile - avoid pagecache and such because we cannot afford | 2818 | /* Read data from quotafile - avoid pagecache and such because we cannot afford |
diff --git a/fs/ext3/xattr_security.c b/fs/ext3/xattr_security.c index 821efaf2b94e..37b81097bdf2 100644 --- a/fs/ext3/xattr_security.c +++ b/fs/ext3/xattr_security.c | |||
@@ -15,7 +15,7 @@ static size_t | |||
15 | ext3_xattr_security_list(struct inode *inode, char *list, size_t list_size, | 15 | ext3_xattr_security_list(struct inode *inode, char *list, size_t list_size, |
16 | const char *name, size_t name_len) | 16 | const char *name, size_t name_len) |
17 | { | 17 | { |
18 | const size_t prefix_len = sizeof(XATTR_SECURITY_PREFIX)-1; | 18 | const size_t prefix_len = XATTR_SECURITY_PREFIX_LEN; |
19 | const size_t total_len = prefix_len + name_len + 1; | 19 | const size_t total_len = prefix_len + name_len + 1; |
20 | 20 | ||
21 | 21 | ||
diff --git a/fs/ext3/xattr_trusted.c b/fs/ext3/xattr_trusted.c index 0327497a55ce..c7c41a410c4b 100644 --- a/fs/ext3/xattr_trusted.c +++ b/fs/ext3/xattr_trusted.c | |||
@@ -13,13 +13,11 @@ | |||
13 | #include <linux/ext3_fs.h> | 13 | #include <linux/ext3_fs.h> |
14 | #include "xattr.h" | 14 | #include "xattr.h" |
15 | 15 | ||
16 | #define XATTR_TRUSTED_PREFIX "trusted." | ||
17 | |||
18 | static size_t | 16 | static size_t |
19 | ext3_xattr_trusted_list(struct inode *inode, char *list, size_t list_size, | 17 | ext3_xattr_trusted_list(struct inode *inode, char *list, size_t list_size, |
20 | const char *name, size_t name_len) | 18 | const char *name, size_t name_len) |
21 | { | 19 | { |
22 | const size_t prefix_len = sizeof(XATTR_TRUSTED_PREFIX)-1; | 20 | const size_t prefix_len = XATTR_TRUSTED_PREFIX_LEN; |
23 | const size_t total_len = prefix_len + name_len + 1; | 21 | const size_t total_len = prefix_len + name_len + 1; |
24 | 22 | ||
25 | if (!capable(CAP_SYS_ADMIN)) | 23 | if (!capable(CAP_SYS_ADMIN)) |
diff --git a/fs/ext3/xattr_user.c b/fs/ext3/xattr_user.c index 1abd8f92c440..430fe63b31b3 100644 --- a/fs/ext3/xattr_user.c +++ b/fs/ext3/xattr_user.c | |||
@@ -12,13 +12,11 @@ | |||
12 | #include <linux/ext3_fs.h> | 12 | #include <linux/ext3_fs.h> |
13 | #include "xattr.h" | 13 | #include "xattr.h" |
14 | 14 | ||
15 | #define XATTR_USER_PREFIX "user." | ||
16 | |||
17 | static size_t | 15 | static size_t |
18 | ext3_xattr_user_list(struct inode *inode, char *list, size_t list_size, | 16 | ext3_xattr_user_list(struct inode *inode, char *list, size_t list_size, |
19 | const char *name, size_t name_len) | 17 | const char *name, size_t name_len) |
20 | { | 18 | { |
21 | const size_t prefix_len = sizeof(XATTR_USER_PREFIX)-1; | 19 | const size_t prefix_len = XATTR_USER_PREFIX_LEN; |
22 | const size_t total_len = prefix_len + name_len + 1; | 20 | const size_t total_len = prefix_len + name_len + 1; |
23 | 21 | ||
24 | if (!test_opt(inode->i_sb, XATTR_USER)) | 22 | if (!test_opt(inode->i_sb, XATTR_USER)) |