From 1d889d9958490888b3fad1d486145d9a03559cbc Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Mon, 30 Mar 2009 14:02:20 -0400 Subject: reiserfs: make some warnings informational In several places, reiserfs_warning is used when there is no warning, just a notice. This patch changes some of them to indicate that the message is merely informational. Signed-off-by: Jeff Mahoney Signed-off-by: Linus Torvalds --- fs/reiserfs/xattr.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'fs/reiserfs/xattr.c') diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index ad92461cbfc3..e11b00472361 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c @@ -1182,12 +1182,10 @@ int reiserfs_xattr_init(struct super_block *s, int mount_flags) } if (dentry && dentry->d_inode) - reiserfs_warning(s, - "Created %s on %s - reserved for " - "xattr storage.", - PRIVROOT_NAME, - reiserfs_bdevname - (inode->i_sb)); + reiserfs_info(s, "Created %s - " + "reserved for xattr " + "storage.\n", + PRIVROOT_NAME); } else if (!dentry->d_inode) { dput(dentry); dentry = NULL; -- cgit v1.2.3 From 45b03d5e8e674eb6555b767e1c8eb40b671ff892 Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Mon, 30 Mar 2009 14:02:21 -0400 Subject: reiserfs: rework reiserfs_warning ReiserFS warnings can be somewhat inconsistent. In some cases: * a unique identifier may be associated with it * the function name may be included * the device may be printed separately This patch aims to make warnings more consistent. reiserfs_warning() prints the device name, so printing it a second time is not required. The function name for a warning is always helpful in debugging, so it is now automatically inserted into the output. Hans has stated that every warning should have a unique identifier. Some cases lack them, others really shouldn't have them. reiserfs_warning() now expects an id associated with each message. In the rare case where one isn't needed, "" will suffice. Signed-off-by: Jeff Mahoney Signed-off-by: Linus Torvalds --- fs/reiserfs/bitmap.c | 52 ++++----- fs/reiserfs/do_balan.c | 40 +++---- fs/reiserfs/file.c | 2 +- fs/reiserfs/fix_node.c | 14 +-- fs/reiserfs/inode.c | 60 +++++----- fs/reiserfs/item_ops.c | 60 +++++----- fs/reiserfs/journal.c | 174 +++++++++++++++------------- fs/reiserfs/lbalance.c | 12 +- fs/reiserfs/namei.c | 45 ++++---- fs/reiserfs/objectid.c | 5 +- fs/reiserfs/prints.c | 11 +- fs/reiserfs/procfs.c | 5 +- fs/reiserfs/stree.c | 107 ++++++++---------- fs/reiserfs/super.c | 257 ++++++++++++++++++++++-------------------- fs/reiserfs/tail_conversion.c | 6 +- fs/reiserfs/xattr.c | 21 ++-- include/linux/reiserfs_fs.h | 9 +- 17 files changed, 454 insertions(+), 426 deletions(-) (limited to 'fs/reiserfs/xattr.c') diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c index 98b92a3da14a..51b116103041 100644 --- a/fs/reiserfs/bitmap.c +++ b/fs/reiserfs/bitmap.c @@ -64,8 +64,8 @@ int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value) unsigned int bmap_count = reiserfs_bmap_count(s); if (block == 0 || block >= SB_BLOCK_COUNT(s)) { - reiserfs_warning(s, - "vs-4010: is_reusable: block number is out of range %lu (%u)", + reiserfs_warning(s, "vs-4010", + "block number is out of range %lu (%u)", block, SB_BLOCK_COUNT(s)); return 0; } @@ -79,30 +79,29 @@ int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value) b_blocknr_t bmap1 = REISERFS_SB(s)->s_sbh->b_blocknr + 1; if (block >= bmap1 && block <= bmap1 + bmap_count) { - reiserfs_warning(s, "vs: 4019: is_reusable: " - "bitmap block %lu(%u) can't be freed or reused", + reiserfs_warning(s, "vs-4019", "bitmap block %lu(%u) " + "can't be freed or reused", block, bmap_count); return 0; } } else { if (offset == 0) { - reiserfs_warning(s, "vs: 4020: is_reusable: " - "bitmap block %lu(%u) can't be freed or reused", + reiserfs_warning(s, "vs-4020", "bitmap block %lu(%u) " + "can't be freed or reused", block, bmap_count); return 0; } } if (bmap >= bmap_count) { - reiserfs_warning(s, - "vs-4030: is_reusable: there is no so many bitmap blocks: " - "block=%lu, bitmap_nr=%u", block, bmap); + reiserfs_warning(s, "vs-4030", "bitmap for requested block " + "is out of range: block=%lu, bitmap_nr=%u", + block, bmap); return 0; } if (bit_value == 0 && block == SB_ROOT_BLOCK(s)) { - reiserfs_warning(s, - "vs-4050: is_reusable: this is root block (%u), " + reiserfs_warning(s, "vs-4050", "this is root block (%u), " "it must be busy", SB_ROOT_BLOCK(s)); return 0; } @@ -154,8 +153,8 @@ static int scan_bitmap_block(struct reiserfs_transaction_handle *th, /* - I mean `a window of zero bits' as in description of this function - Zam. */ if (!bi) { - reiserfs_warning(s, "NULL bitmap info pointer for bitmap %d", - bmap_n); + reiserfs_warning(s, "jdm-4055", "NULL bitmap info pointer " + "for bitmap %d", bmap_n); return 0; } @@ -400,11 +399,8 @@ static void _reiserfs_free_block(struct reiserfs_transaction_handle *th, get_bit_address(s, block, &nr, &offset); if (nr >= reiserfs_bmap_count(s)) { - reiserfs_warning(s, "vs-4075: reiserfs_free_block: " - "block %lu is out of range on %s " - "(nr=%u,max=%u)", block, - reiserfs_bdevname(s), nr, - reiserfs_bmap_count(s)); + reiserfs_warning(s, "vs-4075", "block %lu is out of range", + block); return; } @@ -416,9 +412,8 @@ static void _reiserfs_free_block(struct reiserfs_transaction_handle *th, /* clear bit for the given block in bit map */ if (!reiserfs_test_and_clear_le_bit(offset, bmbh->b_data)) { - reiserfs_warning(s, "vs-4080: reiserfs_free_block: " - "free_block (%s:%lu)[dev:blocknr]: bit already cleared", - reiserfs_bdevname(s), block); + reiserfs_warning(s, "vs-4080", + "block %lu: bit already cleared", block); } apbi[nr].free_count++; journal_mark_dirty(th, s, bmbh); @@ -477,9 +472,8 @@ static void __discard_prealloc(struct reiserfs_transaction_handle *th, BUG_ON(!th->t_trans_id); #ifdef CONFIG_REISERFS_CHECK if (ei->i_prealloc_count < 0) - reiserfs_warning(th->t_super, - "zam-4001:%s: inode has negative prealloc blocks count.", - __func__); + reiserfs_warning(th->t_super, "zam-4001", + "inode has negative prealloc blocks count."); #endif while (ei->i_prealloc_count > 0) { reiserfs_free_prealloc_block(th, inode, ei->i_prealloc_block); @@ -515,9 +509,9 @@ void reiserfs_discard_all_prealloc(struct reiserfs_transaction_handle *th) i_prealloc_list); #ifdef CONFIG_REISERFS_CHECK if (!ei->i_prealloc_count) { - reiserfs_warning(th->t_super, - "zam-4001:%s: inode is in prealloc list but has no preallocated blocks.", - __func__); + reiserfs_warning(th->t_super, "zam-4001", + "inode is in prealloc list but has " + "no preallocated blocks."); } #endif __discard_prealloc(th, ei); @@ -631,8 +625,8 @@ int reiserfs_parse_alloc_options(struct super_block *s, char *options) continue; } - reiserfs_warning(s, "zam-4001: %s : unknown option - %s", - __func__, this_char); + reiserfs_warning(s, "zam-4001", "unknown option - %s", + this_char); return 1; } diff --git a/fs/reiserfs/do_balan.c b/fs/reiserfs/do_balan.c index 99f80538c4bf..f701f37ddf98 100644 --- a/fs/reiserfs/do_balan.c +++ b/fs/reiserfs/do_balan.c @@ -1752,15 +1752,16 @@ static void store_thrown(struct tree_balance *tb, struct buffer_head *bh) int i; if (buffer_dirty(bh)) - reiserfs_warning(tb->tb_sb, - "store_thrown deals with dirty buffer"); + reiserfs_warning(tb->tb_sb, "reiserfs-12320", + "called with dirty buffer"); for (i = 0; i < ARRAY_SIZE(tb->thrown); i++) if (!tb->thrown[i]) { tb->thrown[i] = bh; get_bh(bh); /* free_thrown puts this */ return; } - reiserfs_warning(tb->tb_sb, "store_thrown: too many thrown buffers"); + reiserfs_warning(tb->tb_sb, "reiserfs-12321", + "too many thrown buffers"); } static void free_thrown(struct tree_balance *tb) @@ -1771,8 +1772,8 @@ static void free_thrown(struct tree_balance *tb) if (tb->thrown[i]) { blocknr = tb->thrown[i]->b_blocknr; if (buffer_dirty(tb->thrown[i])) - reiserfs_warning(tb->tb_sb, - "free_thrown deals with dirty buffer %d", + reiserfs_warning(tb->tb_sb, "reiserfs-12322", + "called with dirty buffer %d", blocknr); brelse(tb->thrown[i]); /* incremented in store_thrown */ reiserfs_free_block(tb->transaction_handle, NULL, @@ -1877,13 +1878,12 @@ static void check_internal_node(struct super_block *s, struct buffer_head *bh, } } -static int locked_or_not_in_tree(struct buffer_head *bh, char *which) +static int locked_or_not_in_tree(struct tree_balance *tb, + struct buffer_head *bh, char *which) { if ((!buffer_journal_prepared(bh) && buffer_locked(bh)) || !B_IS_IN_TREE(bh)) { - reiserfs_warning(NULL, - "vs-12339: locked_or_not_in_tree: %s (%b)", - which, bh); + reiserfs_warning(tb->tb_sb, "vs-12339", "%s (%b)", which, bh); return 1; } return 0; @@ -1902,18 +1902,19 @@ static int check_before_balancing(struct tree_balance *tb) /* double check that buffers that we will modify are unlocked. (fix_nodes should already have prepped all of these for us). */ if (tb->lnum[0]) { - retval |= locked_or_not_in_tree(tb->L[0], "L[0]"); - retval |= locked_or_not_in_tree(tb->FL[0], "FL[0]"); - retval |= locked_or_not_in_tree(tb->CFL[0], "CFL[0]"); + retval |= locked_or_not_in_tree(tb, tb->L[0], "L[0]"); + retval |= locked_or_not_in_tree(tb, tb->FL[0], "FL[0]"); + retval |= locked_or_not_in_tree(tb, tb->CFL[0], "CFL[0]"); check_leaf(tb->L[0]); } if (tb->rnum[0]) { - retval |= locked_or_not_in_tree(tb->R[0], "R[0]"); - retval |= locked_or_not_in_tree(tb->FR[0], "FR[0]"); - retval |= locked_or_not_in_tree(tb->CFR[0], "CFR[0]"); + retval |= locked_or_not_in_tree(tb, tb->R[0], "R[0]"); + retval |= locked_or_not_in_tree(tb, tb->FR[0], "FR[0]"); + retval |= locked_or_not_in_tree(tb, tb->CFR[0], "CFR[0]"); check_leaf(tb->R[0]); } - retval |= locked_or_not_in_tree(PATH_PLAST_BUFFER(tb->tb_path), "S[0]"); + retval |= locked_or_not_in_tree(tb, PATH_PLAST_BUFFER(tb->tb_path), + "S[0]"); check_leaf(PATH_PLAST_BUFFER(tb->tb_path)); return retval; @@ -1952,7 +1953,7 @@ static void check_after_balance_leaf(struct tree_balance *tb) PATH_H_POSITION(tb->tb_path, 1)))); print_cur_tb("12223"); - reiserfs_warning(tb->tb_sb, + reiserfs_warning(tb->tb_sb, "reiserfs-12363", "B_FREE_SPACE (PATH_H_PBUFFER(tb->tb_path,0)) = %d; " "MAX_CHILD_SIZE (%d) - dc_size( %y, %d ) [%d] = %d", left, @@ -2104,9 +2105,8 @@ void do_balance(struct tree_balance *tb, /* tree_balance structure */ } /* if we have no real work to do */ if (!tb->insert_size[0]) { - reiserfs_warning(tb->tb_sb, - "PAP-12350: do_balance: insert_size == 0, mode == %c", - flag); + reiserfs_warning(tb->tb_sb, "PAP-12350", + "insert_size == 0, mode == %c", flag); unfix_nodes(tb); return; } diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c index 33408417038c..47bab8978be1 100644 --- a/fs/reiserfs/file.c +++ b/fs/reiserfs/file.c @@ -76,7 +76,7 @@ static int reiserfs_file_release(struct inode *inode, struct file *filp) * and let the admin know what is going on. */ igrab(inode); - reiserfs_warning(inode->i_sb, + reiserfs_warning(inode->i_sb, "clm-9001", "pinning inode %lu because the " "preallocation can't be freed", inode->i_ino); diff --git a/fs/reiserfs/fix_node.c b/fs/reiserfs/fix_node.c index 07d05e0842b7..59735a9e2349 100644 --- a/fs/reiserfs/fix_node.c +++ b/fs/reiserfs/fix_node.c @@ -496,8 +496,8 @@ static int get_num_ver(int mode, struct tree_balance *tb, int h, snum012[needed_nodes - 1 + 3] = units; if (needed_nodes > 2) - reiserfs_warning(tb->tb_sb, "vs-8111: get_num_ver: " - "split_item_position is out of boundary"); + reiserfs_warning(tb->tb_sb, "vs-8111", + "split_item_position is out of range"); snum012[needed_nodes - 1]++; split_item_positions[needed_nodes - 1] = i; needed_nodes++; @@ -533,8 +533,8 @@ static int get_num_ver(int mode, struct tree_balance *tb, int h, if (vn->vn_vi[split_item_num].vi_index != TYPE_DIRENTRY && vn->vn_vi[split_item_num].vi_index != TYPE_INDIRECT) - reiserfs_warning(tb->tb_sb, "vs-8115: get_num_ver: not " - "directory or indirect item"); + reiserfs_warning(tb->tb_sb, "vs-8115", + "not directory or indirect item"); } /* now we know S2bytes, calculate S1bytes */ @@ -2268,9 +2268,9 @@ static int wait_tb_buffers_until_unlocked(struct tree_balance *p_s_tb) #ifdef CONFIG_REISERFS_CHECK repeat_counter++; if ((repeat_counter % 10000) == 0) { - reiserfs_warning(p_s_tb->tb_sb, - "wait_tb_buffers_until_released(): too many " - "iterations waiting for buffer to unlock " + reiserfs_warning(p_s_tb->tb_sb, "reiserfs-8200", + "too many iterations waiting " + "for buffer to unlock " "(%b)", locked); /* Don't loop forever. Try to recover from possible error. */ diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 55fce92cdf18..95157762b1bf 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c @@ -842,7 +842,9 @@ int reiserfs_get_block(struct inode *inode, sector_t block, if (retval) { if (retval != -ENOSPC) reiserfs_warning(inode->i_sb, - "clm-6004: convert tail failed inode %lu, error %d", + "clm-6004", + "convert tail failed " + "inode %lu, error %d", inode->i_ino, retval); if (allocated_block_nr) { @@ -1006,8 +1008,7 @@ int reiserfs_get_block(struct inode *inode, sector_t block, goto failure; } if (retval == POSITION_FOUND) { - reiserfs_warning(inode->i_sb, - "vs-825: reiserfs_get_block: " + reiserfs_warning(inode->i_sb, "vs-825", "%K should not be found", &key); retval = -EEXIST; if (allocated_block_nr) @@ -1332,9 +1333,9 @@ void reiserfs_update_sd_size(struct reiserfs_transaction_handle *th, /* look for the object's stat data */ retval = search_item(inode->i_sb, &key, &path); if (retval == IO_ERROR) { - reiserfs_warning(inode->i_sb, - "vs-13050: reiserfs_update_sd: " - "i/o failure occurred trying to update %K stat data", + reiserfs_warning(inode->i_sb, "vs-13050", + "i/o failure occurred trying to " + "update %K stat data", &key); return; } @@ -1345,9 +1346,9 @@ void reiserfs_update_sd_size(struct reiserfs_transaction_handle *th, /*reiserfs_warning (inode->i_sb, "vs-13050: reiserfs_update_sd: i_nlink == 0, stat data not found"); */ return; } - reiserfs_warning(inode->i_sb, - "vs-13060: reiserfs_update_sd: " - "stat data of object %k (nlink == %d) not found (pos %d)", + reiserfs_warning(inode->i_sb, "vs-13060", + "stat data of object %k (nlink == %d) " + "not found (pos %d)", INODE_PKEY(inode), inode->i_nlink, pos); reiserfs_check_path(&path); @@ -1424,10 +1425,9 @@ void reiserfs_read_locked_inode(struct inode *inode, /* look for the object's stat data */ retval = search_item(inode->i_sb, &key, &path_to_sd); if (retval == IO_ERROR) { - reiserfs_warning(inode->i_sb, - "vs-13070: reiserfs_read_locked_inode: " - "i/o failure occurred trying to find stat data of %K", - &key); + reiserfs_warning(inode->i_sb, "vs-13070", + "i/o failure occurred trying to find " + "stat data of %K", &key); reiserfs_make_bad_inode(inode); return; } @@ -1457,8 +1457,7 @@ void reiserfs_read_locked_inode(struct inode *inode, during mount (fs/reiserfs/super.c:finish_unfinished()). */ if ((inode->i_nlink == 0) && !REISERFS_SB(inode->i_sb)->s_is_unlinked_ok) { - reiserfs_warning(inode->i_sb, - "vs-13075: reiserfs_read_locked_inode: " + reiserfs_warning(inode->i_sb, "vs-13075", "dead inode read from disk %K. " "This is likely to be race with knfsd. Ignore", &key); @@ -1555,7 +1554,7 @@ struct dentry *reiserfs_fh_to_dentry(struct super_block *sb, struct fid *fid, */ if (fh_type > fh_len) { if (fh_type != 6 || fh_len != 5) - reiserfs_warning(sb, + reiserfs_warning(sb, "reiserfs-13077", "nfsd/reiserfs, fhtype=%d, len=%d - odd", fh_type, fh_len); fh_type = 5; @@ -1680,13 +1679,13 @@ static int reiserfs_new_directory(struct reiserfs_transaction_handle *th, /* look for place in the tree for new item */ retval = search_item(sb, &key, path); if (retval == IO_ERROR) { - reiserfs_warning(sb, "vs-13080: reiserfs_new_directory: " + reiserfs_warning(sb, "vs-13080", "i/o failure occurred creating new directory"); return -EIO; } if (retval == ITEM_FOUND) { pathrelse(path); - reiserfs_warning(sb, "vs-13070: reiserfs_new_directory: " + reiserfs_warning(sb, "vs-13070", "object with this key exists (%k)", &(ih->ih_key)); return -EEXIST; @@ -1720,13 +1719,13 @@ static int reiserfs_new_symlink(struct reiserfs_transaction_handle *th, struct i /* look for place in the tree for new item */ retval = search_item(sb, &key, path); if (retval == IO_ERROR) { - reiserfs_warning(sb, "vs-13080: reiserfs_new_symlinik: " + reiserfs_warning(sb, "vs-13080", "i/o failure occurred creating new symlink"); return -EIO; } if (retval == ITEM_FOUND) { pathrelse(path); - reiserfs_warning(sb, "vs-13080: reiserfs_new_symlink: " + reiserfs_warning(sb, "vs-13080", "object with this key exists (%k)", &(ih->ih_key)); return -EEXIST; @@ -1927,7 +1926,8 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, goto out_inserted_sd; } } else if (inode->i_sb->s_flags & MS_POSIXACL) { - reiserfs_warning(inode->i_sb, "ACLs aren't enabled in the fs, " + reiserfs_warning(inode->i_sb, "jdm-13090", + "ACLs aren't enabled in the fs, " "but vfs thinks they are!"); } else if (is_reiserfs_priv_object(dir)) { reiserfs_mark_inode_private(inode); @@ -2044,8 +2044,8 @@ static int grab_tail_page(struct inode *p_s_inode, ** I've screwed up the code to find the buffer, or the code to ** call prepare_write */ - reiserfs_warning(p_s_inode->i_sb, - "clm-6000: error reading block %lu on dev %s", + reiserfs_warning(p_s_inode->i_sb, "clm-6000", + "error reading block %lu on dev %s", bh->b_blocknr, reiserfs_bdevname(p_s_inode->i_sb)); error = -EIO; @@ -2089,8 +2089,8 @@ int reiserfs_truncate_file(struct inode *p_s_inode, int update_timestamps) // and get_block_create_0 could not find a block to read in, // which is ok. if (error != -ENOENT) - reiserfs_warning(p_s_inode->i_sb, - "clm-6001: grab_tail_page failed %d", + reiserfs_warning(p_s_inode->i_sb, "clm-6001", + "grab_tail_page failed %d", error); page = NULL; bh = NULL; @@ -2208,9 +2208,8 @@ static int map_block_for_writepage(struct inode *inode, /* we've found an unformatted node */ if (indirect_item_found(retval, ih)) { if (bytes_copied > 0) { - reiserfs_warning(inode->i_sb, - "clm-6002: bytes_copied %d", - bytes_copied); + reiserfs_warning(inode->i_sb, "clm-6002", + "bytes_copied %d", bytes_copied); } if (!get_block_num(item, pos_in_item)) { /* crap, we are writing to a hole */ @@ -2267,9 +2266,8 @@ static int map_block_for_writepage(struct inode *inode, goto research; } } else { - reiserfs_warning(inode->i_sb, - "clm-6003: bad item inode %lu, device %s", - inode->i_ino, reiserfs_bdevname(inode->i_sb)); + reiserfs_warning(inode->i_sb, "clm-6003", + "bad item inode %lu", inode->i_ino); retval = -EIO; goto out; } diff --git a/fs/reiserfs/item_ops.c b/fs/reiserfs/item_ops.c index 9475557ab499..8a11cf39f57b 100644 --- a/fs/reiserfs/item_ops.c +++ b/fs/reiserfs/item_ops.c @@ -97,7 +97,8 @@ static int sd_unit_num(struct virtual_item *vi) static void sd_print_vi(struct virtual_item *vi) { - reiserfs_warning(NULL, "STATDATA, index %d, type 0x%x, %h", + reiserfs_warning(NULL, "reiserfs-16100", + "STATDATA, index %d, type 0x%x, %h", vi->vi_index, vi->vi_type, vi->vi_ih); } @@ -190,7 +191,8 @@ static int direct_unit_num(struct virtual_item *vi) static void direct_print_vi(struct virtual_item *vi) { - reiserfs_warning(NULL, "DIRECT, index %d, type 0x%x, %h", + reiserfs_warning(NULL, "reiserfs-16101", + "DIRECT, index %d, type 0x%x, %h", vi->vi_index, vi->vi_type, vi->vi_ih); } @@ -278,7 +280,7 @@ static void indirect_print_item(struct item_head *ih, char *item) unp = (__le32 *) item; if (ih_item_len(ih) % UNFM_P_SIZE) - reiserfs_warning(NULL, "indirect_print_item: invalid item len"); + reiserfs_warning(NULL, "reiserfs-16102", "invalid item len"); printk("%d pointers\n[ ", (int)I_UNFM_NUM(ih)); for (j = 0; j < I_UNFM_NUM(ih); j++) { @@ -334,7 +336,8 @@ static int indirect_unit_num(struct virtual_item *vi) static void indirect_print_vi(struct virtual_item *vi) { - reiserfs_warning(NULL, "INDIRECT, index %d, type 0x%x, %h", + reiserfs_warning(NULL, "reiserfs-16103", + "INDIRECT, index %d, type 0x%x, %h", vi->vi_index, vi->vi_type, vi->vi_ih); } @@ -359,7 +362,7 @@ static struct item_operations indirect_ops = { static int direntry_bytes_number(struct item_head *ih, int block_size) { - reiserfs_warning(NULL, "vs-16090: direntry_bytes_number: " + reiserfs_warning(NULL, "vs-16090", "bytes number is asked for direntry"); return 0; } @@ -614,7 +617,8 @@ static void direntry_print_vi(struct virtual_item *vi) int i; struct direntry_uarea *dir_u = vi->vi_uarea; - reiserfs_warning(NULL, "DIRENTRY, index %d, type 0x%x, %h, flags 0x%x", + reiserfs_warning(NULL, "reiserfs-16104", + "DIRENTRY, index %d, type 0x%x, %h, flags 0x%x", vi->vi_index, vi->vi_type, vi->vi_ih, dir_u->flags); printk("%d entries: ", dir_u->entry_count); for (i = 0; i < dir_u->entry_count; i++) @@ -642,43 +646,43 @@ static struct item_operations direntry_ops = { // static int errcatch_bytes_number(struct item_head *ih, int block_size) { - reiserfs_warning(NULL, - "green-16001: Invalid item type observed, run fsck ASAP"); + reiserfs_warning(NULL, "green-16001", + "Invalid item type observed, run fsck ASAP"); return 0; } static void errcatch_decrement_key(struct cpu_key *key) { - reiserfs_warning(NULL, - "green-16002: Invalid item type observed, run fsck ASAP"); + reiserfs_warning(NULL, "green-16002", + "Invalid item type observed, run fsck ASAP"); } static int errcatch_is_left_mergeable(struct reiserfs_key *key, unsigned long bsize) { - reiserfs_warning(NULL, - "green-16003: Invalid item type observed, run fsck ASAP"); + reiserfs_warning(NULL, "green-16003", + "Invalid item type observed, run fsck ASAP"); return 0; } static void errcatch_print_item(struct item_head *ih, char *item) { - reiserfs_warning(NULL, - "green-16004: Invalid item type observed, run fsck ASAP"); + reiserfs_warning(NULL, "green-16004", + "Invalid item type observed, run fsck ASAP"); } static void errcatch_check_item(struct item_head *ih, char *item) { - reiserfs_warning(NULL, - "green-16005: Invalid item type observed, run fsck ASAP"); + reiserfs_warning(NULL, "green-16005", + "Invalid item type observed, run fsck ASAP"); } static int errcatch_create_vi(struct virtual_node *vn, struct virtual_item *vi, int is_affected, int insert_size) { - reiserfs_warning(NULL, - "green-16006: Invalid item type observed, run fsck ASAP"); + reiserfs_warning(NULL, "green-16006", + "Invalid item type observed, run fsck ASAP"); return 0; // We might return -1 here as well, but it won't help as create_virtual_node() from where // this operation is called from is of return type void. } @@ -686,36 +690,36 @@ static int errcatch_create_vi(struct virtual_node *vn, static int errcatch_check_left(struct virtual_item *vi, int free, int start_skip, int end_skip) { - reiserfs_warning(NULL, - "green-16007: Invalid item type observed, run fsck ASAP"); + reiserfs_warning(NULL, "green-16007", + "Invalid item type observed, run fsck ASAP"); return -1; } static int errcatch_check_right(struct virtual_item *vi, int free) { - reiserfs_warning(NULL, - "green-16008: Invalid item type observed, run fsck ASAP"); + reiserfs_warning(NULL, "green-16008", + "Invalid item type observed, run fsck ASAP"); return -1; } static int errcatch_part_size(struct virtual_item *vi, int first, int count) { - reiserfs_warning(NULL, - "green-16009: Invalid item type observed, run fsck ASAP"); + reiserfs_warning(NULL, "green-16009", + "Invalid item type observed, run fsck ASAP"); return 0; } static int errcatch_unit_num(struct virtual_item *vi) { - reiserfs_warning(NULL, - "green-16010: Invalid item type observed, run fsck ASAP"); + reiserfs_warning(NULL, "green-16010", + "Invalid item type observed, run fsck ASAP"); return 0; } static void errcatch_print_vi(struct virtual_item *vi) { - reiserfs_warning(NULL, - "green-16011: Invalid item type observed, run fsck ASAP"); + reiserfs_warning(NULL, "green-16011", + "Invalid item type observed, run fsck ASAP"); } static struct item_operations errcatch_ops = { diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c index 677bb926e7d6..88a031fafd07 100644 --- a/fs/reiserfs/journal.c +++ b/fs/reiserfs/journal.c @@ -300,8 +300,8 @@ int reiserfs_allocate_list_bitmaps(struct super_block *p_s_sb, jb->journal_list = NULL; jb->bitmaps = vmalloc(mem); if (!jb->bitmaps) { - reiserfs_warning(p_s_sb, - "clm-2000, unable to allocate bitmaps for journal lists"); + reiserfs_warning(p_s_sb, "clm-2000", "unable to " + "allocate bitmaps for journal lists"); failed = 1; break; } @@ -644,8 +644,8 @@ static void reiserfs_end_buffer_io_sync(struct buffer_head *bh, int uptodate) char b[BDEVNAME_SIZE]; if (buffer_journaled(bh)) { - reiserfs_warning(NULL, - "clm-2084: pinned buffer %lu:%s sent to disk", + reiserfs_warning(NULL, "clm-2084", + "pinned buffer %lu:%s sent to disk", bh->b_blocknr, bdevname(bh->b_bdev, b)); } if (uptodate) @@ -1122,7 +1122,8 @@ static int flush_commit_list(struct super_block *s, sync_dirty_buffer(tbh); if (unlikely(!buffer_uptodate(tbh))) { #ifdef CONFIG_REISERFS_CHECK - reiserfs_warning(s, "journal-601, buffer write failed"); + reiserfs_warning(s, "journal-601", + "buffer write failed"); #endif retval = -EIO; } @@ -1154,14 +1155,14 @@ static int flush_commit_list(struct super_block *s, * up propagating the write error out to the filesystem. */ if (unlikely(!buffer_uptodate(jl->j_commit_bh))) { #ifdef CONFIG_REISERFS_CHECK - reiserfs_warning(s, "journal-615: buffer write failed"); + reiserfs_warning(s, "journal-615", "buffer write failed"); #endif retval = -EIO; } bforget(jl->j_commit_bh); if (journal->j_last_commit_id != 0 && (jl->j_trans_id - journal->j_last_commit_id) != 1) { - reiserfs_warning(s, "clm-2200: last commit %lu, current %lu", + reiserfs_warning(s, "clm-2200", "last commit %lu, current %lu", journal->j_last_commit_id, jl->j_trans_id); } journal->j_last_commit_id = jl->j_trans_id; @@ -1250,7 +1251,7 @@ static void remove_all_from_journal_list(struct super_block *p_s_sb, while (cn) { if (cn->blocknr != 0) { if (debug) { - reiserfs_warning(p_s_sb, + reiserfs_warning(p_s_sb, "reiserfs-2201", "block %u, bh is %d, state %ld", cn->blocknr, cn->bh ? 1 : 0, cn->state); @@ -1288,8 +1289,8 @@ static int _update_journal_header_block(struct super_block *p_s_sb, wait_on_buffer((journal->j_header_bh)); if (unlikely(!buffer_uptodate(journal->j_header_bh))) { #ifdef CONFIG_REISERFS_CHECK - reiserfs_warning(p_s_sb, - "journal-699: buffer write failed"); + reiserfs_warning(p_s_sb, "journal-699", + "buffer write failed"); #endif return -EIO; } @@ -1319,8 +1320,8 @@ static int _update_journal_header_block(struct super_block *p_s_sb, sync_dirty_buffer(journal->j_header_bh); } if (!buffer_uptodate(journal->j_header_bh)) { - reiserfs_warning(p_s_sb, - "journal-837: IO error during journal replay"); + reiserfs_warning(p_s_sb, "journal-837", + "IO error during journal replay"); return -EIO; } } @@ -1401,8 +1402,7 @@ static int flush_journal_list(struct super_block *s, BUG_ON(j_len_saved <= 0); if (atomic_read(&journal->j_wcount) != 0) { - reiserfs_warning(s, - "clm-2048: flush_journal_list called with wcount %d", + reiserfs_warning(s, "clm-2048", "called with wcount %d", atomic_read(&journal->j_wcount)); } BUG_ON(jl->j_trans_id == 0); @@ -1510,8 +1510,8 @@ static int flush_journal_list(struct super_block *s, ** is not marked JDirty_wait */ if ((!was_jwait) && !buffer_locked(saved_bh)) { - reiserfs_warning(s, - "journal-813: BAD! buffer %llu %cdirty %cjwait, " + reiserfs_warning(s, "journal-813", + "BAD! buffer %llu %cdirty %cjwait, " "not in a newer tranasction", (unsigned long long)saved_bh-> b_blocknr, was_dirty ? ' ' : '!', @@ -1529,8 +1529,8 @@ static int flush_journal_list(struct super_block *s, unlock_buffer(saved_bh); count++; } else { - reiserfs_warning(s, - "clm-2082: Unable to flush buffer %llu in %s", + reiserfs_warning(s, "clm-2082", + "Unable to flush buffer %llu in %s", (unsigned long long)saved_bh-> b_blocknr, __func__); } @@ -1541,8 +1541,8 @@ static int flush_journal_list(struct super_block *s, /* we incremented this to keep others from taking the buffer head away */ put_bh(saved_bh); if (atomic_read(&(saved_bh->b_count)) < 0) { - reiserfs_warning(s, - "journal-945: saved_bh->b_count < 0"); + reiserfs_warning(s, "journal-945", + "saved_bh->b_count < 0"); } } } @@ -1561,8 +1561,8 @@ static int flush_journal_list(struct super_block *s, } if (unlikely(!buffer_uptodate(cn->bh))) { #ifdef CONFIG_REISERFS_CHECK - reiserfs_warning(s, - "journal-949: buffer write failed\n"); + reiserfs_warning(s, "journal-949", + "buffer write failed"); #endif err = -EIO; } @@ -1623,7 +1623,7 @@ static int flush_journal_list(struct super_block *s, if (journal->j_last_flush_id != 0 && (jl->j_trans_id - journal->j_last_flush_id) != 1) { - reiserfs_warning(s, "clm-2201: last flush %lu, current %lu", + reiserfs_warning(s, "clm-2201", "last flush %lu, current %lu", journal->j_last_flush_id, jl->j_trans_id); } journal->j_last_flush_id = jl->j_trans_id; @@ -2058,8 +2058,9 @@ static int journal_transaction_is_valid(struct super_block *p_s_sb, return -1; } if (get_desc_trans_len(desc) > SB_JOURNAL(p_s_sb)->j_trans_max) { - reiserfs_warning(p_s_sb, - "journal-2018: Bad transaction length %d encountered, ignoring transaction", + reiserfs_warning(p_s_sb, "journal-2018", + "Bad transaction length %d " + "encountered, ignoring transaction", get_desc_trans_len(desc)); return -1; } @@ -2195,8 +2196,8 @@ static int journal_read_transaction(struct super_block *p_s_sb, brelse(d_bh); kfree(log_blocks); kfree(real_blocks); - reiserfs_warning(p_s_sb, - "journal-1169: kmalloc failed, unable to mount FS"); + reiserfs_warning(p_s_sb, "journal-1169", + "kmalloc failed, unable to mount FS"); return -1; } /* get all the buffer heads */ @@ -2218,15 +2219,18 @@ static int journal_read_transaction(struct super_block *p_s_sb, j_realblock[i - trans_half])); } if (real_blocks[i]->b_blocknr > SB_BLOCK_COUNT(p_s_sb)) { - reiserfs_warning(p_s_sb, - "journal-1207: REPLAY FAILURE fsck required! Block to replay is outside of filesystem"); + reiserfs_warning(p_s_sb, "journal-1207", + "REPLAY FAILURE fsck required! " + "Block to replay is outside of " + "filesystem"); goto abort_replay; } /* make sure we don't try to replay onto log or reserved area */ if (is_block_in_log_or_reserved_area (p_s_sb, real_blocks[i]->b_blocknr)) { - reiserfs_warning(p_s_sb, - "journal-1204: REPLAY FAILURE fsck required! Trying to replay onto a log block"); + reiserfs_warning(p_s_sb, "journal-1204", + "REPLAY FAILURE fsck required! " + "Trying to replay onto a log block"); abort_replay: brelse_array(log_blocks, i); brelse_array(real_blocks, i); @@ -2242,8 +2246,9 @@ static int journal_read_transaction(struct super_block *p_s_sb, for (i = 0; i < get_desc_trans_len(desc); i++) { wait_on_buffer(log_blocks[i]); if (!buffer_uptodate(log_blocks[i])) { - reiserfs_warning(p_s_sb, - "journal-1212: REPLAY FAILURE fsck required! buffer write failed"); + reiserfs_warning(p_s_sb, "journal-1212", + "REPLAY FAILURE fsck required! " + "buffer write failed"); brelse_array(log_blocks + i, get_desc_trans_len(desc) - i); brelse_array(real_blocks, get_desc_trans_len(desc)); @@ -2266,8 +2271,9 @@ static int journal_read_transaction(struct super_block *p_s_sb, for (i = 0; i < get_desc_trans_len(desc); i++) { wait_on_buffer(real_blocks[i]); if (!buffer_uptodate(real_blocks[i])) { - reiserfs_warning(p_s_sb, - "journal-1226: REPLAY FAILURE, fsck required! buffer write failed"); + reiserfs_warning(p_s_sb, "journal-1226", + "REPLAY FAILURE, fsck required! " + "buffer write failed"); brelse_array(real_blocks + i, get_desc_trans_len(desc) - i); brelse(c_bh); @@ -2418,8 +2424,8 @@ static int journal_read(struct super_block *p_s_sb) } if (continue_replay && bdev_read_only(p_s_sb->s_bdev)) { - reiserfs_warning(p_s_sb, - "clm-2076: device is readonly, unable to replay log"); + reiserfs_warning(p_s_sb, "clm-2076", + "device is readonly, unable to replay log"); return -1; } @@ -2580,9 +2586,8 @@ static int release_journal_dev(struct super_block *super, } if (result != 0) { - reiserfs_warning(super, - "sh-457: release_journal_dev: Cannot release journal device: %i", - result); + reiserfs_warning(super, "sh-457", + "Cannot release journal device: %i", result); } return result; } @@ -2612,7 +2617,7 @@ static int journal_init_dev(struct super_block *super, if (IS_ERR(journal->j_dev_bd)) { result = PTR_ERR(journal->j_dev_bd); journal->j_dev_bd = NULL; - reiserfs_warning(super, "sh-458: journal_init_dev: " + reiserfs_warning(super, "sh-458", "cannot init journal device '%s': %i", __bdevname(jdev, b), result); return result; @@ -2676,16 +2681,16 @@ static int check_advise_trans_params(struct super_block *p_s_sb, journal->j_trans_max < JOURNAL_TRANS_MIN_DEFAULT / ratio || SB_ONDISK_JOURNAL_SIZE(p_s_sb) / journal->j_trans_max < JOURNAL_MIN_RATIO) { - reiserfs_warning(p_s_sb, - "sh-462: bad transaction max size (%u). FSCK?", - journal->j_trans_max); + reiserfs_warning(p_s_sb, "sh-462", + "bad transaction max size (%u). " + "FSCK?", journal->j_trans_max); return 1; } if (journal->j_max_batch != (journal->j_trans_max) * JOURNAL_MAX_BATCH_DEFAULT/JOURNAL_TRANS_MAX_DEFAULT) { - reiserfs_warning(p_s_sb, - "sh-463: bad transaction max batch (%u). FSCK?", - journal->j_max_batch); + reiserfs_warning(p_s_sb, "sh-463", + "bad transaction max batch (%u). " + "FSCK?", journal->j_max_batch); return 1; } } else { @@ -2693,9 +2698,11 @@ static int check_advise_trans_params(struct super_block *p_s_sb, The file system was created by old version of mkreiserfs, so some fields contain zeros, and we need to advise proper values for them */ - if (p_s_sb->s_blocksize != REISERFS_STANDARD_BLKSIZE) - reiserfs_panic(p_s_sb, "sh-464: bad blocksize (%u)", - p_s_sb->s_blocksize); + if (p_s_sb->s_blocksize != REISERFS_STANDARD_BLKSIZE) { + reiserfs_warning(p_s_sb, "sh-464", "bad blocksize (%u)", + p_s_sb->s_blocksize); + return 1; + } journal->j_trans_max = JOURNAL_TRANS_MAX_DEFAULT; journal->j_max_batch = JOURNAL_MAX_BATCH_DEFAULT; journal->j_max_commit_age = JOURNAL_MAX_COMMIT_AGE; @@ -2719,8 +2726,8 @@ int journal_init(struct super_block *p_s_sb, const char *j_dev_name, journal = SB_JOURNAL(p_s_sb) = vmalloc(sizeof(struct reiserfs_journal)); if (!journal) { - reiserfs_warning(p_s_sb, - "journal-1256: unable to get memory for journal structure"); + reiserfs_warning(p_s_sb, "journal-1256", + "unable to get memory for journal structure"); return 1; } memset(journal, 0, sizeof(struct reiserfs_journal)); @@ -2749,9 +2756,9 @@ int journal_init(struct super_block *p_s_sb, const char *j_dev_name, if (!SB_ONDISK_JOURNAL_DEVICE(p_s_sb) && (SB_JOURNAL_1st_RESERVED_BLOCK(p_s_sb) + SB_ONDISK_JOURNAL_SIZE(p_s_sb) > p_s_sb->s_blocksize * 8)) { - reiserfs_warning(p_s_sb, - "journal-1393: journal does not fit for area " - "addressed by first of bitmap blocks. It starts at " + reiserfs_warning(p_s_sb, "journal-1393", + "journal does not fit for area addressed " + "by first of bitmap blocks. It starts at " "%u and its size is %u. Block size %ld", SB_JOURNAL_1st_RESERVED_BLOCK(p_s_sb), SB_ONDISK_JOURNAL_SIZE(p_s_sb), @@ -2760,8 +2767,8 @@ int journal_init(struct super_block *p_s_sb, const char *j_dev_name, } if (journal_init_dev(p_s_sb, journal, j_dev_name) != 0) { - reiserfs_warning(p_s_sb, - "sh-462: unable to initialize jornal device"); + reiserfs_warning(p_s_sb, "sh-462", + "unable to initialize jornal device"); goto free_and_return; } @@ -2772,8 +2779,8 @@ int journal_init(struct super_block *p_s_sb, const char *j_dev_name, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + SB_ONDISK_JOURNAL_SIZE(p_s_sb)); if (!bhjh) { - reiserfs_warning(p_s_sb, - "sh-459: unable to read journal header"); + reiserfs_warning(p_s_sb, "sh-459", + "unable to read journal header"); goto free_and_return; } jh = (struct reiserfs_journal_header *)(bhjh->b_data); @@ -2782,10 +2789,10 @@ int journal_init(struct super_block *p_s_sb, const char *j_dev_name, if (is_reiserfs_jr(rs) && (le32_to_cpu(jh->jh_journal.jp_journal_magic) != sb_jp_journal_magic(rs))) { - reiserfs_warning(p_s_sb, - "sh-460: journal header magic %x " - "(device %s) does not match to magic found in super " - "block %x", jh->jh_journal.jp_journal_magic, + reiserfs_warning(p_s_sb, "sh-460", + "journal header magic %x (device %s) does " + "not match to magic found in super block %x", + jh->jh_journal.jp_journal_magic, bdevname(journal->j_dev_bd, b), sb_jp_journal_magic(rs)); brelse(bhjh); @@ -2852,7 +2859,7 @@ int journal_init(struct super_block *p_s_sb, const char *j_dev_name, journal->j_must_wait = 0; if (journal->j_cnode_free == 0) { - reiserfs_warning(p_s_sb, "journal-2004: Journal cnode memory " + reiserfs_warning(p_s_sb, "journal-2004", "Journal cnode memory " "allocation failed (%ld bytes). Journal is " "too large for available memory. Usually " "this is due to a journal that is too large.", @@ -2864,12 +2871,13 @@ int journal_init(struct super_block *p_s_sb, const char *j_dev_name, jl = journal->j_current_jl; jl->j_list_bitmap = get_list_bitmap(p_s_sb, jl); if (!jl->j_list_bitmap) { - reiserfs_warning(p_s_sb, - "journal-2005, get_list_bitmap failed for journal list 0"); + reiserfs_warning(p_s_sb, "journal-2005", + "get_list_bitmap failed for journal list 0"); goto free_and_return; } if (journal_read(p_s_sb) < 0) { - reiserfs_warning(p_s_sb, "Replay Failure, unable to mount"); + reiserfs_warning(p_s_sb, "reiserfs-2006", + "Replay Failure, unable to mount"); goto free_and_return; } @@ -3196,16 +3204,17 @@ int journal_begin(struct reiserfs_transaction_handle *th, cur_th->t_refcount++; memcpy(th, cur_th, sizeof(*th)); if (th->t_refcount <= 1) - reiserfs_warning(p_s_sb, - "BAD: refcount <= 1, but journal_info != 0"); + reiserfs_warning(p_s_sb, "reiserfs-2005", + "BAD: refcount <= 1, but " + "journal_info != 0"); return 0; } else { /* we've ended up with a handle from a different filesystem. ** save it and restore on journal_end. This should never ** really happen... */ - reiserfs_warning(p_s_sb, - "clm-2100: nesting info a different FS"); + reiserfs_warning(p_s_sb, "clm-2100", + "nesting info a different FS"); th->t_handle_save = current->journal_info; current->journal_info = th; } @@ -3266,7 +3275,8 @@ int journal_mark_dirty(struct reiserfs_transaction_handle *th, ** could get to disk too early. NOT GOOD. */ if (!prepared || buffer_dirty(bh)) { - reiserfs_warning(p_s_sb, "journal-1777: buffer %llu bad state " + reiserfs_warning(p_s_sb, "journal-1777", + "buffer %llu bad state " "%cPREPARED %cLOCKED %cDIRTY %cJDIRTY_WAIT", (unsigned long long)bh->b_blocknr, prepared ? ' ' : '!', @@ -3276,8 +3286,8 @@ int journal_mark_dirty(struct reiserfs_transaction_handle *th, } if (atomic_read(&(journal->j_wcount)) <= 0) { - reiserfs_warning(p_s_sb, - "journal-1409: journal_mark_dirty returning because j_wcount was %d", + reiserfs_warning(p_s_sb, "journal-1409", + "returning because j_wcount was %d", atomic_read(&(journal->j_wcount))); return 1; } @@ -3342,8 +3352,8 @@ int journal_end(struct reiserfs_transaction_handle *th, struct super_block *p_s_sb, unsigned long nblocks) { if (!current->journal_info && th->t_refcount > 1) - reiserfs_warning(p_s_sb, "REISER-NESTING: th NULL, refcount %d", - th->t_refcount); + reiserfs_warning(p_s_sb, "REISER-NESTING", + "th NULL, refcount %d", th->t_refcount); if (!th->t_trans_id) { WARN_ON(1); @@ -3413,8 +3423,8 @@ static int remove_from_transaction(struct super_block *p_s_sb, clear_buffer_journal_test(bh); put_bh(bh); if (atomic_read(&(bh->b_count)) < 0) { - reiserfs_warning(p_s_sb, - "journal-1752: remove from trans, b_count < 0"); + reiserfs_warning(p_s_sb, "journal-1752", + "b_count < 0"); } ret = 1; } @@ -3734,7 +3744,8 @@ int journal_mark_freed(struct reiserfs_transaction_handle *th, if (atomic_read (&(cn->bh->b_count)) < 0) { reiserfs_warning(p_s_sb, - "journal-2138: cn->bh->b_count < 0"); + "journal-2138", + "cn->bh->b_count < 0"); } } if (cn->jlist) { /* since we are clearing the bh, we MUST dec nonzerolen */ @@ -4137,8 +4148,9 @@ static int do_journal_end(struct reiserfs_transaction_handle *th, clear_buffer_journaled(cn->bh); } else { /* JDirty cleared sometime during transaction. don't log this one */ - reiserfs_warning(p_s_sb, - "journal-2048: do_journal_end: BAD, buffer in journal hash, but not JDirty!"); + reiserfs_warning(p_s_sb, "journal-2048", + "BAD, buffer in journal hash, " + "but not JDirty!"); brelse(cn->bh); } next = cn->next; diff --git a/fs/reiserfs/lbalance.c b/fs/reiserfs/lbalance.c index 41bdd8c75887..381339b432e7 100644 --- a/fs/reiserfs/lbalance.c +++ b/fs/reiserfs/lbalance.c @@ -1288,12 +1288,16 @@ void leaf_paste_entries(struct buffer_info *bi, prev = (i != 0) ? deh_location(&(deh[i - 1])) : 0; if (prev && prev <= deh_location(&(deh[i]))) - reiserfs_warning(NULL, - "vs-10240: leaf_paste_entries: directory item (%h) corrupted (prev %a, cur(%d) %a)", + reiserfs_warning(NULL, "vs-10240", + "directory item (%h) " + "corrupted (prev %a, " + "cur(%d) %a)", ih, deh + i - 1, i, deh + i); if (next && next >= deh_location(&(deh[i]))) - reiserfs_warning(NULL, - "vs-10250: leaf_paste_entries: directory item (%h) corrupted (cur(%d) %a, next %a)", + reiserfs_warning(NULL, "vs-10250", + "directory item (%h) " + "corrupted (cur(%d) %a, " + "next %a)", ih, i, deh + i, deh + i + 1); } } diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index 738967f6c8ee..bb41c6e7c79b 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c @@ -120,8 +120,8 @@ int search_by_entry_key(struct super_block *sb, const struct cpu_key *key, switch (retval) { case ITEM_NOT_FOUND: if (!PATH_LAST_POSITION(path)) { - reiserfs_warning(sb, - "vs-7000: search_by_entry_key: search_by_key returned item position == 0"); + reiserfs_warning(sb, "vs-7000", "search_by_key " + "returned item position == 0"); pathrelse(path); return IO_ERROR; } @@ -135,8 +135,7 @@ int search_by_entry_key(struct super_block *sb, const struct cpu_key *key, default: pathrelse(path); - reiserfs_warning(sb, - "vs-7002: search_by_entry_key: no path to here"); + reiserfs_warning(sb, "vs-7002", "no path to here"); return IO_ERROR; } @@ -300,8 +299,7 @@ static int reiserfs_find_entry(struct inode *dir, const char *name, int namelen, search_by_entry_key(dir->i_sb, &key_to_search, path_to_entry, de); if (retval == IO_ERROR) { - reiserfs_warning(dir->i_sb, "zam-7001: io error in %s", - __func__); + reiserfs_warning(dir->i_sb, "zam-7001", "io error"); return IO_ERROR; } @@ -484,10 +482,9 @@ static int reiserfs_add_entry(struct reiserfs_transaction_handle *th, } if (retval != NAME_FOUND) { - reiserfs_warning(dir->i_sb, - "zam-7002:%s: \"reiserfs_find_entry\" " - "has returned unexpected value (%d)", - __func__, retval); + reiserfs_warning(dir->i_sb, "zam-7002", + "reiserfs_find_entry() returned " + "unexpected value (%d)", retval); } return -EEXIST; @@ -498,8 +495,9 @@ static int reiserfs_add_entry(struct reiserfs_transaction_handle *th, MAX_GENERATION_NUMBER + 1); if (gen_number > MAX_GENERATION_NUMBER) { /* there is no free generation number */ - reiserfs_warning(dir->i_sb, - "reiserfs_add_entry: Congratulations! we have got hash function screwed up"); + reiserfs_warning(dir->i_sb, "reiserfs-7010", + "Congratulations! we have got hash function " + "screwed up"); if (buffer != small_buf) kfree(buffer); pathrelse(&path); @@ -515,10 +513,9 @@ static int reiserfs_add_entry(struct reiserfs_transaction_handle *th, if (gen_number != 0) { /* we need to re-search for the insertion point */ if (search_by_entry_key(dir->i_sb, &entry_key, &path, &de) != NAME_NOT_FOUND) { - reiserfs_warning(dir->i_sb, - "vs-7032: reiserfs_add_entry: " - "entry with this key (%K) already exists", - &entry_key); + reiserfs_warning(dir->i_sb, "vs-7032", + "entry with this key (%K) already " + "exists", &entry_key); if (buffer != small_buf) kfree(buffer); @@ -903,8 +900,9 @@ static int reiserfs_rmdir(struct inode *dir, struct dentry *dentry) goto end_rmdir; if (inode->i_nlink != 2 && inode->i_nlink != 1) - reiserfs_warning(inode->i_sb, "%s: empty directory has nlink " - "!= 2 (%d)", __func__, inode->i_nlink); + reiserfs_warning(inode->i_sb, "reiserfs-7040", + "empty directory has nlink != 2 (%d)", + inode->i_nlink); clear_nlink(inode); inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; @@ -980,10 +978,9 @@ static int reiserfs_unlink(struct inode *dir, struct dentry *dentry) } if (!inode->i_nlink) { - reiserfs_warning(inode->i_sb, "%s: deleting nonexistent file " - "(%s:%lu), %d", __func__, - reiserfs_bdevname(inode->i_sb), inode->i_ino, - inode->i_nlink); + reiserfs_warning(inode->i_sb, "reiserfs-7042", + "deleting nonexistent file (%lu), %d", + inode->i_ino, inode->i_nlink); inode->i_nlink = 1; } @@ -1499,8 +1496,8 @@ static int reiserfs_rename(struct inode *old_dir, struct dentry *old_dentry, if (reiserfs_cut_from_item (&th, &old_entry_path, &(old_de.de_entry_key), old_dir, NULL, 0) < 0) - reiserfs_warning(old_dir->i_sb, - "vs-7060: reiserfs_rename: couldn't not cut old name. Fsck later?"); + reiserfs_warning(old_dir->i_sb, "vs-7060", + "couldn't not cut old name. Fsck later?"); old_dir->i_size -= DEH_SIZE + old_de.de_entrylen; diff --git a/fs/reiserfs/objectid.c b/fs/reiserfs/objectid.c index ea0cf8c28a99..a3a5f43ff443 100644 --- a/fs/reiserfs/objectid.c +++ b/fs/reiserfs/objectid.c @@ -61,7 +61,7 @@ __u32 reiserfs_get_unused_objectid(struct reiserfs_transaction_handle *th) /* comment needed -Hans */ unused_objectid = le32_to_cpu(map[1]); if (unused_objectid == U32_MAX) { - reiserfs_warning(s, "%s: no more object ids", __func__); + reiserfs_warning(s, "reiserfs-15100", "no more object ids"); reiserfs_restore_prepared_buffer(s, SB_BUFFER_WITH_SB(s)); return 0; } @@ -160,8 +160,7 @@ void reiserfs_release_objectid(struct reiserfs_transaction_handle *th, i += 2; } - reiserfs_warning(s, - "vs-15011: reiserfs_release_objectid: tried to free free object id (%lu)", + reiserfs_warning(s, "vs-15011", "tried to free free object id (%lu)", (long unsigned)objectid_to_release); } diff --git a/fs/reiserfs/prints.c b/fs/reiserfs/prints.c index 535a3c7fc68e..50ed4bd3ef63 100644 --- a/fs/reiserfs/prints.c +++ b/fs/reiserfs/prints.c @@ -264,14 +264,17 @@ static void prepare_error_buf(const char *fmt, va_list args) va_end( args );\ } -void reiserfs_warning(struct super_block *sb, const char *fmt, ...) +void __reiserfs_warning(struct super_block *sb, const char *id, + const char *function, const char *fmt, ...) { do_reiserfs_warning(fmt); if (sb) - printk(KERN_WARNING "REISERFS warning (device %s): %s\n", - sb->s_id, error_buf); + printk(KERN_WARNING "REISERFS warning (device %s): %s%s%s: " + "%s\n", sb->s_id, id ? id : "", id ? " " : "", + function, error_buf); else - printk(KERN_WARNING "REISERFS warning: %s\n", error_buf); + printk(KERN_WARNING "REISERFS warning: %s%s%s: %s\n", + id ? id : "", id ? " " : "", function, error_buf); } /* No newline.. reiserfs_info calls can be followed by printk's */ diff --git a/fs/reiserfs/procfs.c b/fs/reiserfs/procfs.c index 370988efc8ad..d4d7f1433ed0 100644 --- a/fs/reiserfs/procfs.c +++ b/fs/reiserfs/procfs.c @@ -503,7 +503,7 @@ int reiserfs_proc_info_init(struct super_block *sb) add_file(sb, "journal", show_journal); return 0; } - reiserfs_warning(sb, "reiserfs: cannot create /proc/%s/%s", + reiserfs_warning(sb, "cannot create /proc/%s/%s", proc_info_root_name, b); return 1; } @@ -559,8 +559,7 @@ int reiserfs_proc_info_global_init(void) if (proc_info_root) { proc_info_root->owner = THIS_MODULE; } else { - reiserfs_warning(NULL, - "reiserfs: cannot create /proc/%s", + reiserfs_warning(NULL, "cannot create /proc/%s", proc_info_root_name); return 1; } diff --git a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c index abbc64dcc8d4..f328d27a19d5 100644 --- a/fs/reiserfs/stree.c +++ b/fs/reiserfs/stree.c @@ -444,23 +444,24 @@ static int is_leaf(char *buf, int blocksize, struct buffer_head *bh) blkh = (struct block_head *)buf; if (blkh_level(blkh) != DISK_LEAF_NODE_LEVEL) { - reiserfs_warning(NULL, - "is_leaf: this should be caught earlier"); + reiserfs_warning(NULL, "reiserfs-5080", + "this should be caught earlier"); return 0; } nr = blkh_nr_item(blkh); if (nr < 1 || nr > ((blocksize - BLKH_SIZE) / (IH_SIZE + MIN_ITEM_LEN))) { /* item number is too big or too small */ - reiserfs_warning(NULL, "is_leaf: nr_item seems wrong: %z", bh); + reiserfs_warning(NULL, "reiserfs-5081", + "nr_item seems wrong: %z", bh); return 0; } ih = (struct item_head *)(buf + BLKH_SIZE) + nr - 1; used_space = BLKH_SIZE + IH_SIZE * nr + (blocksize - ih_location(ih)); if (used_space != blocksize - blkh_free_space(blkh)) { /* free space does not match to calculated amount of use space */ - reiserfs_warning(NULL, "is_leaf: free space seems wrong: %z", - bh); + reiserfs_warning(NULL, "reiserfs-5082", + "free space seems wrong: %z", bh); return 0; } // FIXME: it is_leaf will hit performance too much - we may have @@ -471,29 +472,29 @@ static int is_leaf(char *buf, int blocksize, struct buffer_head *bh) prev_location = blocksize; for (i = 0; i < nr; i++, ih++) { if (le_ih_k_type(ih) == TYPE_ANY) { - reiserfs_warning(NULL, - "is_leaf: wrong item type for item %h", + reiserfs_warning(NULL, "reiserfs-5083", + "wrong item type for item %h", ih); return 0; } if (ih_location(ih) >= blocksize || ih_location(ih) < IH_SIZE * nr) { - reiserfs_warning(NULL, - "is_leaf: item location seems wrong: %h", + reiserfs_warning(NULL, "reiserfs-5084", + "item location seems wrong: %h", ih); return 0; } if (ih_item_len(ih) < 1 || ih_item_len(ih) > MAX_ITEM_LEN(blocksize)) { - reiserfs_warning(NULL, - "is_leaf: item length seems wrong: %h", + reiserfs_warning(NULL, "reiserfs-5085", + "item length seems wrong: %h", ih); return 0; } if (prev_location - ih_location(ih) != ih_item_len(ih)) { - reiserfs_warning(NULL, - "is_leaf: item location seems wrong (second one): %h", - ih); + reiserfs_warning(NULL, "reiserfs-5086", + "item location seems wrong " + "(second one): %h", ih); return 0; } prev_location = ih_location(ih); @@ -514,24 +515,23 @@ static int is_internal(char *buf, int blocksize, struct buffer_head *bh) nr = blkh_level(blkh); if (nr <= DISK_LEAF_NODE_LEVEL || nr > MAX_HEIGHT) { /* this level is not possible for internal nodes */ - reiserfs_warning(NULL, - "is_internal: this should be caught earlier"); + reiserfs_warning(NULL, "reiserfs-5087", + "this should be caught earlier"); return 0; } nr = blkh_nr_item(blkh); if (nr > (blocksize - BLKH_SIZE - DC_SIZE) / (KEY_SIZE + DC_SIZE)) { /* for internal which is not root we might check min number of keys */ - reiserfs_warning(NULL, - "is_internal: number of key seems wrong: %z", - bh); + reiserfs_warning(NULL, "reiserfs-5088", + "number of key seems wrong: %z", bh); return 0; } used_space = BLKH_SIZE + KEY_SIZE * nr + DC_SIZE * (nr + 1); if (used_space != blocksize - blkh_free_space(blkh)) { - reiserfs_warning(NULL, - "is_internal: free space seems wrong: %z", bh); + reiserfs_warning(NULL, "reiserfs-5089", + "free space seems wrong: %z", bh); return 0; } // one may imagine much more checks @@ -543,8 +543,8 @@ static int is_internal(char *buf, int blocksize, struct buffer_head *bh) static int is_tree_node(struct buffer_head *bh, int level) { if (B_LEVEL(bh) != level) { - reiserfs_warning(NULL, - "is_tree_node: node level %d does not match to the expected one %d", + reiserfs_warning(NULL, "reiserfs-5090", "node level %d does " + "not match to the expected one %d", B_LEVEL(bh), level); return 0; } @@ -645,9 +645,9 @@ int search_by_key(struct super_block *p_s_sb, const struct cpu_key *p_s_key, /* #ifdef CONFIG_REISERFS_CHECK if (!(++n_repeat_counter % 50000)) - reiserfs_warning(p_s_sb, "PAP-5100: search_by_key: %s:" - "there were %d iterations of while loop " - "looking for key %K", + reiserfs_warning(p_s_sb, "PAP-5100", + "%s: there were %d iterations of " + "while loop looking for key %K", current->comm, n_repeat_counter, p_s_key); #endif @@ -721,9 +721,9 @@ int search_by_key(struct super_block *p_s_sb, const struct cpu_key *p_s_key, /* // make sure, that the node contents look like a node of // certain level if (!is_tree_node(p_s_bh, expected_level)) { - reiserfs_warning(p_s_sb, "vs-5150: search_by_key: " - "invalid format found in block %ld. Fsck?", - p_s_bh->b_blocknr); + reiserfs_warning(p_s_sb, "vs-5150", + "invalid format found in block %ld. " + "Fsck?", p_s_bh->b_blocknr); pathrelse(p_s_search_path); return IO_ERROR; } @@ -1227,8 +1227,7 @@ int reiserfs_delete_item(struct reiserfs_transaction_handle *th, struct treepath if (n_ret_value == IO_ERROR) break; if (n_ret_value == FILE_NOT_FOUND) { - reiserfs_warning(p_s_sb, - "vs-5340: reiserfs_delete_item: " + reiserfs_warning(p_s_sb, "vs-5340", "no items of the file %K found", p_s_item_key); break; @@ -1338,10 +1337,9 @@ void reiserfs_delete_solid_item(struct reiserfs_transaction_handle *th, while (1) { retval = search_item(th->t_super, &cpu_key, &path); if (retval == IO_ERROR) { - reiserfs_warning(th->t_super, - "vs-5350: reiserfs_delete_solid_item: " - "i/o failure occurred trying to delete %K", - &cpu_key); + reiserfs_warning(th->t_super, "vs-5350", + "i/o failure occurred trying " + "to delete %K", &cpu_key); break; } if (retval != ITEM_FOUND) { @@ -1355,9 +1353,8 @@ void reiserfs_delete_solid_item(struct reiserfs_transaction_handle *th, GET_GENERATION_NUMBER(le_key_k_offset (le_key_version(key), key)) == 1)) - reiserfs_warning(th->t_super, - "vs-5355: reiserfs_delete_solid_item: %k not found", - key); + reiserfs_warning(th->t_super, "vs-5355", + "%k not found", key); break; } if (!tb_init) { @@ -1389,8 +1386,7 @@ void reiserfs_delete_solid_item(struct reiserfs_transaction_handle *th, break; } // IO_ERROR, NO_DISK_SPACE, etc - reiserfs_warning(th->t_super, - "vs-5360: reiserfs_delete_solid_item: " + reiserfs_warning(th->t_super, "vs-5360", "could not delete %K due to fix_nodes failure", &cpu_key); unfix_nodes(&tb); @@ -1533,8 +1529,9 @@ static void indirect_to_direct_roll_back(struct reiserfs_transaction_handle *th, set_cpu_key_k_offset(&tail_key, cpu_key_k_offset(&tail_key) - removed); } - reiserfs_warning(inode->i_sb, - "indirect_to_direct_roll_back: indirect_to_direct conversion has been rolled back due to lack of disk space"); + reiserfs_warning(inode->i_sb, "reiserfs-5091", "indirect_to_direct " + "conversion has been rolled back due to " + "lack of disk space"); //mark_file_without_tail (inode); mark_inode_dirty(inode); } @@ -1639,8 +1636,7 @@ int reiserfs_cut_from_item(struct reiserfs_transaction_handle *th, if (n_ret_value == POSITION_FOUND) continue; - reiserfs_warning(p_s_sb, - "PAP-5610: reiserfs_cut_from_item: item %K not found", + reiserfs_warning(p_s_sb, "PAP-5610", "item %K not found", p_s_item_key); unfix_nodes(&s_cut_balance); return (n_ret_value == IO_ERROR) ? -EIO : -ENOENT; @@ -1654,7 +1650,8 @@ int reiserfs_cut_from_item(struct reiserfs_transaction_handle *th, indirect_to_direct_roll_back(th, p_s_inode, p_s_path); } if (n_ret_value == NO_DISK_SPACE) - reiserfs_warning(p_s_sb, "NO_DISK_SPACE"); + reiserfs_warning(p_s_sb, "reiserfs-5092", + "NO_DISK_SPACE"); unfix_nodes(&s_cut_balance); return -EIO; } @@ -1743,8 +1740,7 @@ static void truncate_directory(struct reiserfs_transaction_handle *th, { BUG_ON(!th->t_trans_id); if (inode->i_nlink) - reiserfs_warning(inode->i_sb, - "vs-5655: truncate_directory: link count != 0"); + reiserfs_warning(inode->i_sb, "vs-5655", "link count != 0"); set_le_key_k_offset(KEY_FORMAT_3_5, INODE_PKEY(inode), DOT_OFFSET); set_le_key_k_type(KEY_FORMAT_3_5, INODE_PKEY(inode), TYPE_DIRENTRY); @@ -1797,16 +1793,14 @@ int reiserfs_do_truncate(struct reiserfs_transaction_handle *th, struct inode *p search_for_position_by_key(p_s_inode->i_sb, &s_item_key, &s_search_path); if (retval == IO_ERROR) { - reiserfs_warning(p_s_inode->i_sb, - "vs-5657: reiserfs_do_truncate: " + reiserfs_warning(p_s_inode->i_sb, "vs-5657", "i/o failure occurred trying to truncate %K", &s_item_key); err = -EIO; goto out; } if (retval == POSITION_FOUND || retval == FILE_NOT_FOUND) { - reiserfs_warning(p_s_inode->i_sb, - "PAP-5660: reiserfs_do_truncate: " + reiserfs_warning(p_s_inode->i_sb, "PAP-5660", "wrong result %d of search for %K", retval, &s_item_key); @@ -1850,8 +1844,8 @@ int reiserfs_do_truncate(struct reiserfs_transaction_handle *th, struct inode *p reiserfs_cut_from_item(th, &s_search_path, &s_item_key, p_s_inode, page, n_new_file_size); if (n_deleted < 0) { - reiserfs_warning(p_s_inode->i_sb, - "vs-5665: reiserfs_do_truncate: reiserfs_cut_from_item failed"); + reiserfs_warning(p_s_inode->i_sb, "vs-5665", + "reiserfs_cut_from_item failed"); reiserfs_check_path(&s_search_path); return 0; } @@ -2000,8 +1994,8 @@ int reiserfs_paste_into_item(struct reiserfs_transaction_handle *th, struct tree goto error_out; } if (retval == POSITION_FOUND) { - reiserfs_warning(inode->i_sb, - "PAP-5710: reiserfs_paste_into_item: entry or pasted byte (%K) exists", + reiserfs_warning(inode->i_sb, "PAP-5710", + "entry or pasted byte (%K) exists", p_s_key); retval = -EEXIST; goto error_out; @@ -2087,8 +2081,7 @@ int reiserfs_insert_item(struct reiserfs_transaction_handle *th, struct treepath goto error_out; } if (retval == ITEM_FOUND) { - reiserfs_warning(th->t_super, - "PAP-5760: reiserfs_insert_item: " + reiserfs_warning(th->t_super, "PAP-5760", "key %K already exists in the tree", key); retval = -EEXIST; diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 0428004dc638..bfc276c8e978 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -183,9 +183,9 @@ static int finish_unfinished(struct super_block *s) if (REISERFS_SB(s)->s_qf_names[i]) { int ret = reiserfs_quota_on_mount(s, i); if (ret < 0) - reiserfs_warning(s, - "reiserfs: cannot turn on journaled quota: error %d", - ret); + reiserfs_warning(s, "reiserfs-2500", + "cannot turn on journaled " + "quota: error %d", ret); } } #endif @@ -195,8 +195,8 @@ static int finish_unfinished(struct super_block *s) while (!retval) { retval = search_item(s, &max_cpu_key, &path); if (retval != ITEM_NOT_FOUND) { - reiserfs_warning(s, - "vs-2140: finish_unfinished: search_by_key returned %d", + reiserfs_warning(s, "vs-2140", + "search_by_key returned %d", retval); break; } @@ -204,8 +204,8 @@ static int finish_unfinished(struct super_block *s) bh = get_last_bh(&path); item_pos = get_item_pos(&path); if (item_pos != B_NR_ITEMS(bh)) { - reiserfs_warning(s, - "vs-2060: finish_unfinished: wrong position found"); + reiserfs_warning(s, "vs-2060", + "wrong position found"); break; } item_pos--; @@ -235,8 +235,7 @@ static int finish_unfinished(struct super_block *s) if (!inode) { /* the unlink almost completed, it just did not manage to remove "save" link and release objectid */ - reiserfs_warning(s, - "vs-2180: finish_unfinished: iget failed for %K", + reiserfs_warning(s, "vs-2180", "iget failed for %K", &obj_key); retval = remove_save_link_only(s, &save_link_key, 1); continue; @@ -244,8 +243,8 @@ static int finish_unfinished(struct super_block *s) if (!truncate && inode->i_nlink) { /* file is not unlinked */ - reiserfs_warning(s, - "vs-2185: finish_unfinished: file %K is not unlinked", + reiserfs_warning(s, "vs-2185", + "file %K is not unlinked", &obj_key); retval = remove_save_link_only(s, &save_link_key, 0); continue; @@ -257,8 +256,9 @@ static int finish_unfinished(struct super_block *s) The only imaginable way is to execute unfinished truncate request then boot into old kernel, remove the file and create dir with the same key. */ - reiserfs_warning(s, - "green-2101: impossible truncate on a directory %k. Please report", + reiserfs_warning(s, "green-2101", + "impossible truncate on a " + "directory %k. Please report", INODE_PKEY(inode)); retval = remove_save_link_only(s, &save_link_key, 0); truncate = 0; @@ -288,9 +288,10 @@ static int finish_unfinished(struct super_block *s) /* removal gets completed in iput */ retval = 0; } else { - reiserfs_warning(s, "Dead loop in " - "finish_unfinished detected, " - "just remove save link\n"); + reiserfs_warning(s, "super-2189", "Dead loop " + "in finish_unfinished " + "detected, just remove " + "save link\n"); retval = remove_save_link_only(s, &save_link_key, 0); } @@ -360,8 +361,9 @@ void add_save_link(struct reiserfs_transaction_handle *th, } else { /* truncate */ if (S_ISDIR(inode->i_mode)) - reiserfs_warning(inode->i_sb, - "green-2102: Adding a truncate savelink for a directory %k! Please report", + reiserfs_warning(inode->i_sb, "green-2102", + "Adding a truncate savelink for " + "a directory %k! Please report", INODE_PKEY(inode)); set_cpu_key_k_offset(&key, 1); set_cpu_key_k_type(&key, TYPE_INDIRECT); @@ -376,7 +378,7 @@ void add_save_link(struct reiserfs_transaction_handle *th, retval = search_item(inode->i_sb, &key, &path); if (retval != ITEM_NOT_FOUND) { if (retval != -ENOSPC) - reiserfs_warning(inode->i_sb, "vs-2100: add_save_link:" + reiserfs_warning(inode->i_sb, "vs-2100", "search_by_key (%K) returned %d", &key, retval); pathrelse(&path); @@ -391,9 +393,8 @@ void add_save_link(struct reiserfs_transaction_handle *th, reiserfs_insert_item(th, &path, &key, &ih, NULL, (char *)&link); if (retval) { if (retval != -ENOSPC) - reiserfs_warning(inode->i_sb, - "vs-2120: add_save_link: insert_item returned %d", - retval); + reiserfs_warning(inode->i_sb, "vs-2120", + "insert_item returned %d", retval); } else { if (truncate) REISERFS_I(inode)->i_flags |= @@ -492,8 +493,7 @@ static void reiserfs_put_super(struct super_block *s) print_statistics(s); if (REISERFS_SB(s)->reserved_blocks != 0) { - reiserfs_warning(s, - "green-2005: reiserfs_put_super: reserved blocks left %d", + reiserfs_warning(s, "green-2005", "reserved blocks left %d", REISERFS_SB(s)->reserved_blocks); } @@ -559,8 +559,8 @@ static void reiserfs_dirty_inode(struct inode *inode) int err = 0; if (inode->i_sb->s_flags & MS_RDONLY) { - reiserfs_warning(inode->i_sb, - "clm-6006: writing inode %lu on readonly FS", + reiserfs_warning(inode->i_sb, "clm-6006", + "writing inode %lu on readonly FS", inode->i_ino); return; } @@ -794,13 +794,15 @@ static int reiserfs_getopt(struct super_block *s, char **cur, opt_desc_t * opts, if (bit_flags) { if (opt->clrmask == (1 << REISERFS_UNSUPPORTED_OPT)) - reiserfs_warning(s, "%s not supported.", + reiserfs_warning(s, "super-6500", + "%s not supported.\n", p); else *bit_flags &= ~opt->clrmask; if (opt->setmask == (1 << REISERFS_UNSUPPORTED_OPT)) - reiserfs_warning(s, "%s not supported.", + reiserfs_warning(s, "super-6501", + "%s not supported.\n", p); else *bit_flags |= opt->setmask; @@ -809,7 +811,8 @@ static int reiserfs_getopt(struct super_block *s, char **cur, opt_desc_t * opts, } } if (!opt->option_name) { - reiserfs_warning(s, "unknown mount option \"%s\"", p); + reiserfs_warning(s, "super-6502", + "unknown mount option \"%s\"", p); return -1; } @@ -817,8 +820,9 @@ static int reiserfs_getopt(struct super_block *s, char **cur, opt_desc_t * opts, switch (*p) { case '=': if (!opt->arg_required) { - reiserfs_warning(s, - "the option \"%s\" does not require an argument", + reiserfs_warning(s, "super-6503", + "the option \"%s\" does not " + "require an argument\n", opt->option_name); return -1; } @@ -826,14 +830,15 @@ static int reiserfs_getopt(struct super_block *s, char **cur, opt_desc_t * opts, case 0: if (opt->arg_required) { - reiserfs_warning(s, - "the option \"%s\" requires an argument", - opt->option_name); + reiserfs_warning(s, "super-6504", + "the option \"%s\" requires an " + "argument\n", opt->option_name); return -1; } break; default: - reiserfs_warning(s, "head of option \"%s\" is only correct", + reiserfs_warning(s, "super-6505", + "head of option \"%s\" is only correct\n", opt->option_name); return -1; } @@ -845,7 +850,8 @@ static int reiserfs_getopt(struct super_block *s, char **cur, opt_desc_t * opts, && !(opt->arg_required & (1 << REISERFS_OPT_ALLOWEMPTY)) && !strlen(p)) { /* this catches "option=," if not allowed */ - reiserfs_warning(s, "empty argument for \"%s\"", + reiserfs_warning(s, "super-6506", + "empty argument for \"%s\"\n", opt->option_name); return -1; } @@ -867,7 +873,8 @@ static int reiserfs_getopt(struct super_block *s, char **cur, opt_desc_t * opts, } } - reiserfs_warning(s, "bad value \"%s\" for option \"%s\"", p, + reiserfs_warning(s, "super-6506", + "bad value \"%s\" for option \"%s\"\n", p, opt->option_name); return -1; } @@ -957,9 +964,9 @@ static int reiserfs_parse_options(struct super_block *s, char *options, /* strin *blocks = simple_strtoul(arg, &p, 0); if (*p != '\0') { /* NNN does not look like a number */ - reiserfs_warning(s, - "reiserfs_parse_options: bad value %s", - arg); + reiserfs_warning(s, "super-6507", + "bad value %s for " + "-oresize\n", arg); return 0; } } @@ -970,8 +977,8 @@ static int reiserfs_parse_options(struct super_block *s, char *options, /* strin unsigned long val = simple_strtoul(arg, &p, 0); /* commit=NNN (time in seconds) */ if (*p != '\0' || val >= (unsigned int)-1) { - reiserfs_warning(s, - "reiserfs_parse_options: bad value %s", + reiserfs_warning(s, "super-6508", + "bad value %s for -ocommit\n", arg); return 0; } @@ -979,16 +986,18 @@ static int reiserfs_parse_options(struct super_block *s, char *options, /* strin } if (c == 'w') { - reiserfs_warning(s, "reiserfs: nolargeio option is no longer supported"); + reiserfs_warning(s, "super-6509", "nolargeio option " + "is no longer supported"); return 0; } if (c == 'j') { if (arg && *arg && jdev_name) { if (*jdev_name) { //Hm, already assigned? - reiserfs_warning(s, - "reiserfs_parse_options: journal device was already specified to be %s", - *jdev_name); + reiserfs_warning(s, "super-6510", + "journal device was " + "already specified to " + "be %s", *jdev_name); return 0; } *jdev_name = arg; @@ -1000,29 +1009,35 @@ static int reiserfs_parse_options(struct super_block *s, char *options, /* strin if (sb_any_quota_loaded(s) && (!*arg != !REISERFS_SB(s)->s_qf_names[qtype])) { - reiserfs_warning(s, - "reiserfs_parse_options: cannot change journaled quota options when quota turned on."); + reiserfs_warning(s, "super-6511", + "cannot change journaled " + "quota options when quota " + "turned on."); return 0; } if (*arg) { /* Some filename specified? */ if (REISERFS_SB(s)->s_qf_names[qtype] && strcmp(REISERFS_SB(s)->s_qf_names[qtype], arg)) { - reiserfs_warning(s, - "reiserfs_parse_options: %s quota file already specified.", + reiserfs_warning(s, "super-6512", + "%s quota file " + "already specified.", QTYPE2NAME(qtype)); return 0; } if (strchr(arg, '/')) { - reiserfs_warning(s, - "reiserfs_parse_options: quotafile must be on filesystem root."); + reiserfs_warning(s, "super-6513", + "quotafile must be " + "on filesystem root."); return 0; } qf_names[qtype] = kmalloc(strlen(arg) + 1, GFP_KERNEL); if (!qf_names[qtype]) { - reiserfs_warning(s, - "reiserfs_parse_options: not enough memory for storing quotafile name."); + reiserfs_warning(s, "reiserfs-2502", + "not enough memory " + "for storing " + "quotafile name."); return 0; } strcpy(qf_names[qtype], arg); @@ -1040,21 +1055,24 @@ static int reiserfs_parse_options(struct super_block *s, char *options, /* strin else if (!strcmp(arg, "vfsv0")) *qfmt = QFMT_VFS_V0; else { - reiserfs_warning(s, - "reiserfs_parse_options: unknown quota format specified."); + reiserfs_warning(s, "super-6514", + "unknown quota format " + "specified."); return 0; } if (sb_any_quota_loaded(s) && *qfmt != REISERFS_SB(s)->s_jquota_fmt) { - reiserfs_warning(s, - "reiserfs_parse_options: cannot change journaled quota options when quota turned on."); + reiserfs_warning(s, "super-6515", + "cannot change journaled " + "quota options when quota " + "turned on."); return 0; } } #else if (c == 'u' || c == 'g' || c == 'f') { - reiserfs_warning(s, - "reiserfs_parse_options: journaled quota options not supported."); + reiserfs_warning(s, "reiserfs-2503", "journaled " + "quota options not supported."); return 0; } #endif @@ -1063,15 +1081,15 @@ static int reiserfs_parse_options(struct super_block *s, char *options, /* strin #ifdef CONFIG_QUOTA if (!REISERFS_SB(s)->s_jquota_fmt && !*qfmt && (qf_names[USRQUOTA] || qf_names[GRPQUOTA])) { - reiserfs_warning(s, - "reiserfs_parse_options: journaled quota format not specified."); + reiserfs_warning(s, "super-6515", + "journaled quota format not specified."); return 0; } /* This checking is not precise wrt the quota type but for our purposes it is sufficient */ if (!(*mount_options & (1 << REISERFS_QUOTA)) && sb_any_quota_loaded(s)) { - reiserfs_warning(s, - "reiserfs_parse_options: quota options must be present when quota is turned on."); + reiserfs_warning(s, "super-6516", "quota options must " + "be present when quota is turned on."); return 0; } #endif @@ -1131,14 +1149,15 @@ static void handle_attrs(struct super_block *s) if (reiserfs_attrs(s)) { if (old_format_only(s)) { - reiserfs_warning(s, - "reiserfs: cannot support attributes on 3.5.x disk format"); + reiserfs_warning(s, "super-6517", "cannot support " + "attributes on 3.5.x disk format"); REISERFS_SB(s)->s_mount_opt &= ~(1 << REISERFS_ATTRS); return; } if (!(le32_to_cpu(rs->s_flags) & reiserfs_attrs_cleared)) { - reiserfs_warning(s, - "reiserfs: cannot support attributes until flag is set in super-block"); + reiserfs_warning(s, "super-6518", "cannot support " + "attributes until flag is set in " + "super-block"); REISERFS_SB(s)->s_mount_opt &= ~(1 << REISERFS_ATTRS); } } @@ -1316,7 +1335,7 @@ static int read_super_block(struct super_block *s, int offset) bh = sb_bread(s, offset / s->s_blocksize); if (!bh) { - reiserfs_warning(s, "sh-2006: read_super_block: " + reiserfs_warning(s, "sh-2006", "bread failed (dev %s, block %lu, size %lu)", reiserfs_bdevname(s), offset / s->s_blocksize, s->s_blocksize); @@ -1337,8 +1356,8 @@ static int read_super_block(struct super_block *s, int offset) bh = sb_bread(s, offset / s->s_blocksize); if (!bh) { - reiserfs_warning(s, "sh-2007: read_super_block: " - "bread failed (dev %s, block %lu, size %lu)\n", + reiserfs_warning(s, "sh-2007", + "bread failed (dev %s, block %lu, size %lu)", reiserfs_bdevname(s), offset / s->s_blocksize, s->s_blocksize); return 1; @@ -1346,8 +1365,8 @@ static int read_super_block(struct super_block *s, int offset) rs = (struct reiserfs_super_block *)bh->b_data; if (sb_blocksize(rs) != s->s_blocksize) { - reiserfs_warning(s, "sh-2011: read_super_block: " - "can't find a reiserfs filesystem on (dev %s, block %Lu, size %lu)\n", + reiserfs_warning(s, "sh-2011", "can't find a reiserfs " + "filesystem on (dev %s, block %Lu, size %lu)", reiserfs_bdevname(s), (unsigned long long)bh->b_blocknr, s->s_blocksize); @@ -1357,9 +1376,10 @@ static int read_super_block(struct super_block *s, int offset) if (rs->s_v1.s_root_block == cpu_to_le32(-1)) { brelse(bh); - reiserfs_warning(s, - "Unfinished reiserfsck --rebuild-tree run detected. Please run\n" - "reiserfsck --rebuild-tree and wait for a completion. If that fails\n" + reiserfs_warning(s, "super-6519", "Unfinished reiserfsck " + "--rebuild-tree run detected. Please run\n" + "reiserfsck --rebuild-tree and wait for a " + "completion. If that fails\n" "get newer reiserfsprogs package"); return 1; } @@ -1377,10 +1397,9 @@ static int read_super_block(struct super_block *s, int offset) reiserfs_info(s, "found reiserfs format \"3.5\"" " with non-standard journal\n"); else { - reiserfs_warning(s, - "sh-2012: read_super_block: found unknown " - "format \"%u\" of reiserfs with non-standard magic", - sb_version(rs)); + reiserfs_warning(s, "sh-2012", "found unknown " + "format \"%u\" of reiserfs with " + "non-standard magic", sb_version(rs)); return 1; } } else @@ -1410,8 +1429,7 @@ static int reread_meta_blocks(struct super_block *s) ll_rw_block(READ, 1, &(SB_BUFFER_WITH_SB(s))); wait_on_buffer(SB_BUFFER_WITH_SB(s)); if (!buffer_uptodate(SB_BUFFER_WITH_SB(s))) { - reiserfs_warning(s, - "reread_meta_blocks, error reading the super"); + reiserfs_warning(s, "reiserfs-2504", "error reading the super"); return 1; } @@ -1475,10 +1493,10 @@ static __u32 find_hash_out(struct super_block *s) && (yurahash == GET_HASH_VALUE(deh_offset (&(de.de_deh[de.de_entry_num])))))) { - reiserfs_warning(s, - "Unable to automatically detect hash function. " - "Please mount with -o hash={tea,rupasov,r5}", - reiserfs_bdevname(s)); + reiserfs_warning(s, "reiserfs-2506", "Unable to " + "automatically detect hash function. " + "Please mount with -o " + "hash={tea,rupasov,r5}"); hash = UNSET_HASH; break; } @@ -1492,7 +1510,8 @@ static __u32 find_hash_out(struct super_block *s) (deh_offset(&(de.de_deh[de.de_entry_num]))) == r5hash) hash = R5_HASH; else { - reiserfs_warning(s, "Unrecognised hash function"); + reiserfs_warning(s, "reiserfs-2506", + "Unrecognised hash function"); hash = UNSET_HASH; } } while (0); @@ -1520,17 +1539,20 @@ static int what_hash(struct super_block *s) ** mount options */ if (reiserfs_rupasov_hash(s) && code != YURA_HASH) { - reiserfs_warning(s, "Error, %s hash detected, " + reiserfs_warning(s, "reiserfs-2507", + "Error, %s hash detected, " "unable to force rupasov hash", reiserfs_hashname(code)); code = UNSET_HASH; } else if (reiserfs_tea_hash(s) && code != TEA_HASH) { - reiserfs_warning(s, "Error, %s hash detected, " + reiserfs_warning(s, "reiserfs-2508", + "Error, %s hash detected, " "unable to force tea hash", reiserfs_hashname(code)); code = UNSET_HASH; } else if (reiserfs_r5_hash(s) && code != R5_HASH) { - reiserfs_warning(s, "Error, %s hash detected, " + reiserfs_warning(s, "reiserfs-2509", + "Error, %s hash detected, " "unable to force r5 hash", reiserfs_hashname(code)); code = UNSET_HASH; @@ -1589,9 +1611,9 @@ static int function2code(hashf_t func) return 0; } -#define SWARN(silent, s, ...) \ +#define SWARN(silent, s, id, ...) \ if (!(silent)) \ - reiserfs_warning (s, __VA_ARGS__) + reiserfs_warning(s, id, __VA_ARGS__) static int reiserfs_fill_super(struct super_block *s, void *data, int silent) { @@ -1643,8 +1665,7 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) #endif if (blocks) { - SWARN(silent, s, "jmacd-7: reiserfs_fill_super: resize option " - "for remount only"); + SWARN(silent, s, "jmacd-7", "resize option for remount only"); goto error; } @@ -1653,8 +1674,7 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) old_format = 1; /* try new format (64-th 1k block), which can contain reiserfs super block */ else if (read_super_block(s, REISERFS_DISK_OFFSET_IN_BYTES)) { - SWARN(silent, s, - "sh-2021: reiserfs_fill_super: can not find reiserfs on %s", + SWARN(silent, s, "sh-2021", "can not find reiserfs on %s", reiserfs_bdevname(s)); goto error; } @@ -1666,13 +1686,12 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) if (s->s_bdev && s->s_bdev->bd_inode && i_size_read(s->s_bdev->bd_inode) < sb_block_count(rs) * sb_blocksize(rs)) { - SWARN(silent, s, - "Filesystem on %s cannot be mounted because it is bigger than the device", - reiserfs_bdevname(s)); - SWARN(silent, s, - "You may need to run fsck or increase size of your LVM partition"); - SWARN(silent, s, - "Or may be you forgot to reboot after fdisk when it told you to"); + SWARN(silent, s, "", "Filesystem cannot be " + "mounted because it is bigger than the device"); + SWARN(silent, s, "", "You may need to run fsck " + "or increase size of your LVM partition"); + SWARN(silent, s, "", "Or may be you forgot to " + "reboot after fdisk when it told you to"); goto error; } @@ -1680,14 +1699,13 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) sbi->s_mount_state = REISERFS_VALID_FS; if ((errval = reiserfs_init_bitmap_cache(s))) { - SWARN(silent, s, - "jmacd-8: reiserfs_fill_super: unable to read bitmap"); + SWARN(silent, s, "jmacd-8", "unable to read bitmap"); goto error; } errval = -EINVAL; #ifdef CONFIG_REISERFS_CHECK - SWARN(silent, s, "CONFIG_REISERFS_CHECK is set ON"); - SWARN(silent, s, "- it is slow mode for debugging."); + SWARN(silent, s, "", "CONFIG_REISERFS_CHECK is set ON"); + SWARN(silent, s, "", "- it is slow mode for debugging."); #endif /* make data=ordered the default */ @@ -1708,8 +1726,8 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) } // set_device_ro(s->s_dev, 1) ; if (journal_init(s, jdev_name, old_format, commit_max_age)) { - SWARN(silent, s, - "sh-2022: reiserfs_fill_super: unable to initialize journal space"); + SWARN(silent, s, "sh-2022", + "unable to initialize journal space"); goto error; } else { jinit_done = 1; /* once this is set, journal_release must be called @@ -1717,8 +1735,8 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) */ } if (reread_meta_blocks(s)) { - SWARN(silent, s, - "jmacd-9: reiserfs_fill_super: unable to reread meta blocks after journal init"); + SWARN(silent, s, "jmacd-9", + "unable to reread meta blocks after journal init"); goto error; } @@ -1726,8 +1744,8 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) goto error; if (bdev_read_only(s->s_bdev) && !(s->s_flags & MS_RDONLY)) { - SWARN(silent, s, - "clm-7000: Detected readonly device, marking FS readonly"); + SWARN(silent, s, "clm-7000", + "Detected readonly device, marking FS readonly"); s->s_flags |= MS_RDONLY; } args.objectid = REISERFS_ROOT_OBJECTID; @@ -1736,8 +1754,7 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) iget5_locked(s, REISERFS_ROOT_OBJECTID, reiserfs_find_actor, reiserfs_init_locked_inode, (void *)(&args)); if (!root_inode) { - SWARN(silent, s, - "jmacd-10: reiserfs_fill_super: get root inode failed"); + SWARN(silent, s, "jmacd-10", "get root inode failed"); goto error; } @@ -1786,7 +1803,7 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) * avoiding corruption. -jeffm */ if (bmap_would_wrap(reiserfs_bmap_count(s)) && sb_bmap_nr(rs) != 0) { - reiserfs_warning(s, "super-2030: This file system " + reiserfs_warning(s, "super-2030", "This file system " "claims to use %u bitmap blocks in " "its super block, but requires %u. " "Clearing to zero.", sb_bmap_nr(rs), @@ -2087,8 +2104,8 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id, if (!(REISERFS_I(inode)->i_flags & i_nopack_mask)) { err = reiserfs_unpack(inode, NULL); if (err) { - reiserfs_warning(sb, - "reiserfs: Unpacking tail of quota file failed" + reiserfs_warning(sb, "super-6520", + "Unpacking tail of quota file failed" " (%d). Cannot turn on quotas.", err); err = -EINVAL; goto out; @@ -2099,8 +2116,8 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id, if (REISERFS_SB(sb)->s_qf_names[type]) { /* Quotafile not of fs root? */ if (path.dentry->d_parent != sb->s_root) - reiserfs_warning(sb, - "reiserfs: Quota file not on filesystem root. " + reiserfs_warning(sb, "super-6521", + "Quota file not on filesystem root. " "Journalled quota will not work."); } diff --git a/fs/reiserfs/tail_conversion.c b/fs/reiserfs/tail_conversion.c index f8121a1147e8..256285dddb20 100644 --- a/fs/reiserfs/tail_conversion.c +++ b/fs/reiserfs/tail_conversion.c @@ -48,9 +48,9 @@ int direct2indirect(struct reiserfs_transaction_handle *th, struct inode *inode, // FIXME: we could avoid this if (search_for_position_by_key(sb, &end_key, path) == POSITION_FOUND) { - reiserfs_warning(sb, "PAP-14030: direct2indirect: " - "pasted or inserted byte exists in the tree %K. " - "Use fsck to repair.", &end_key); + reiserfs_warning(sb, "PAP-14030", + "pasted or inserted byte exists in " + "the tree %K. Use fsck to repair.", &end_key); pathrelse(path); return -EIO; } diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index e11b00472361..d14f5c2c0e4a 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c @@ -259,7 +259,8 @@ static int __xattr_readdir(struct inode *inode, void *dirent, filldir_t filldir) ih = de.de_ih; if (!is_direntry_le_ih(ih)) { - reiserfs_warning(inode->i_sb, "not direntry %h", ih); + reiserfs_warning(inode->i_sb, "jdm-20000", + "not direntry %h", ih); break; } copy_item_head(&tmp_ih, ih); @@ -598,7 +599,7 @@ reiserfs_xattr_get(const struct inode *inode, const char *name, void *buffer, if (rxh->h_magic != cpu_to_le32(REISERFS_XATTR_MAGIC)) { unlock_page(page); reiserfs_put_page(page); - reiserfs_warning(inode->i_sb, + reiserfs_warning(inode->i_sb, "jdm-20001", "Invalid magic for xattr (%s) " "associated with %k", name, INODE_PKEY(inode)); @@ -618,7 +619,7 @@ reiserfs_xattr_get(const struct inode *inode, const char *name, void *buffer, if (xattr_hash(buffer, isize - sizeof(struct reiserfs_xattr_header)) != hash) { - reiserfs_warning(inode->i_sb, + reiserfs_warning(inode->i_sb, "jdm-20002", "Invalid hash for xattr (%s) associated " "with %k", name, INODE_PKEY(inode)); err = -EIO; @@ -652,7 +653,8 @@ __reiserfs_xattr_del(struct dentry *xadir, const char *name, int namelen) goto out_file; if (!is_reiserfs_priv_object(dentry->d_inode)) { - reiserfs_warning(dir->i_sb, "OID %08x [%.*s/%.*s] doesn't have " + reiserfs_warning(dir->i_sb, "jdm-20003", + "OID %08x [%.*s/%.*s] doesn't have " "priv flag set [parent is %sset].", le32_to_cpu(INODE_PKEY(dentry->d_inode)-> k_objectid), xadir->d_name.len, @@ -750,7 +752,7 @@ int reiserfs_delete_xattrs(struct inode *inode) reiserfs_write_unlock_xattrs(inode->i_sb); dput(root); } else { - reiserfs_warning(inode->i_sb, + reiserfs_warning(inode->i_sb, "jdm-20006", "Couldn't remove all entries in directory"); } unlock_kernel(); @@ -1154,7 +1156,8 @@ int reiserfs_xattr_init(struct super_block *s, int mount_flags) } else if (reiserfs_xattrs_optional(s)) { /* Old format filesystem, but optional xattrs have been enabled * at mount time. Error out. */ - reiserfs_warning(s, "xattrs/ACLs not supported on pre v3.6 " + reiserfs_warning(s, "jdm-20005", + "xattrs/ACLs not supported on pre v3.6 " "format filesystem. Failing mount."); err = -EOPNOTSUPP; goto error; @@ -1201,8 +1204,10 @@ int reiserfs_xattr_init(struct super_block *s, int mount_flags) /* If we're read-only it just means that the dir hasn't been * created. Not an error -- just no xattrs on the fs. We'll * check again if we go read-write */ - reiserfs_warning(s, "xattrs/ACLs enabled and couldn't " - "find/create .reiserfs_priv. Failing mount."); + reiserfs_warning(s, "jdm-20006", + "xattrs/ACLs enabled and couldn't " + "find/create .reiserfs_priv. " + "Failing mount."); err = -EOPNOTSUPP; } } diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h index 65bb5e3e3abe..056e2a3b04e3 100644 --- a/include/linux/reiserfs_fs.h +++ b/include/linux/reiserfs_fs.h @@ -79,7 +79,10 @@ struct fid; */ #define REISERFS_DEBUG_CODE 5 /* extra messages to help find/debug errors */ -void reiserfs_warning(struct super_block *s, const char *fmt, ...); +void __reiserfs_warning(struct super_block *s, const char *id, + const char *func, const char *fmt, ...); +#define reiserfs_warning(s, id, fmt, args...) \ + __reiserfs_warning(s, id, __func__, fmt, ##args) /* assertions handling */ /** always check a condition and panic if it's false. */ @@ -558,7 +561,7 @@ static inline int uniqueness2type(__u32 uniqueness) case V1_DIRENTRY_UNIQUENESS: return TYPE_DIRENTRY; default: - reiserfs_warning(NULL, "vs-500: unknown uniqueness %d", + reiserfs_warning(NULL, "vs-500", "unknown uniqueness %d", uniqueness); case V1_ANY_UNIQUENESS: return TYPE_ANY; @@ -578,7 +581,7 @@ static inline __u32 type2uniqueness(int type) case TYPE_DIRENTRY: return V1_DIRENTRY_UNIQUENESS; default: - reiserfs_warning(NULL, "vs-501: unknown type %d", type); + reiserfs_warning(NULL, "vs-501", "unknown type %d", type); case TYPE_ANY: return V1_ANY_UNIQUENESS; } -- cgit v1.2.3 From 0030b64570c862f04c1550ba4a0bf7a9c128162a Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Mon, 30 Mar 2009 14:02:28 -0400 Subject: reiserfs: use reiserfs_error() This patch makes many paths that are currently using warnings to handle the error. Signed-off-by: Jeff Mahoney Signed-off-by: Linus Torvalds --- fs/reiserfs/bitmap.c | 56 ++++++++++++++++++++++--------------------- fs/reiserfs/inode.c | 45 ++++++++++++++++------------------ fs/reiserfs/lbalance.c | 20 ++++++++-------- fs/reiserfs/namei.c | 24 +++++++++---------- fs/reiserfs/objectid.c | 4 ++-- fs/reiserfs/stree.c | 26 ++++++++++---------- fs/reiserfs/super.c | 15 ++++++------ fs/reiserfs/tail_conversion.c | 6 ++--- fs/reiserfs/xattr.c | 21 ++++++++-------- 9 files changed, 107 insertions(+), 110 deletions(-) (limited to 'fs/reiserfs/xattr.c') diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c index 51b116103041..9fc228703ef0 100644 --- a/fs/reiserfs/bitmap.c +++ b/fs/reiserfs/bitmap.c @@ -64,9 +64,9 @@ int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value) unsigned int bmap_count = reiserfs_bmap_count(s); if (block == 0 || block >= SB_BLOCK_COUNT(s)) { - reiserfs_warning(s, "vs-4010", - "block number is out of range %lu (%u)", - block, SB_BLOCK_COUNT(s)); + reiserfs_error(s, "vs-4010", + "block number is out of range %lu (%u)", + block, SB_BLOCK_COUNT(s)); return 0; } @@ -79,30 +79,30 @@ int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value) b_blocknr_t bmap1 = REISERFS_SB(s)->s_sbh->b_blocknr + 1; if (block >= bmap1 && block <= bmap1 + bmap_count) { - reiserfs_warning(s, "vs-4019", "bitmap block %lu(%u) " - "can't be freed or reused", - block, bmap_count); + reiserfs_error(s, "vs-4019", "bitmap block %lu(%u) " + "can't be freed or reused", + block, bmap_count); return 0; } } else { if (offset == 0) { - reiserfs_warning(s, "vs-4020", "bitmap block %lu(%u) " - "can't be freed or reused", - block, bmap_count); + reiserfs_error(s, "vs-4020", "bitmap block %lu(%u) " + "can't be freed or reused", + block, bmap_count); return 0; } } if (bmap >= bmap_count) { - reiserfs_warning(s, "vs-4030", "bitmap for requested block " - "is out of range: block=%lu, bitmap_nr=%u", - block, bmap); + reiserfs_error(s, "vs-4030", "bitmap for requested block " + "is out of range: block=%lu, bitmap_nr=%u", + block, bmap); return 0; } if (bit_value == 0 && block == SB_ROOT_BLOCK(s)) { - reiserfs_warning(s, "vs-4050", "this is root block (%u), " - "it must be busy", SB_ROOT_BLOCK(s)); + reiserfs_error(s, "vs-4050", "this is root block (%u), " + "it must be busy", SB_ROOT_BLOCK(s)); return 0; } @@ -153,8 +153,8 @@ static int scan_bitmap_block(struct reiserfs_transaction_handle *th, /* - I mean `a window of zero bits' as in description of this function - Zam. */ if (!bi) { - reiserfs_warning(s, "jdm-4055", "NULL bitmap info pointer " - "for bitmap %d", bmap_n); + reiserfs_error(s, "jdm-4055", "NULL bitmap info pointer " + "for bitmap %d", bmap_n); return 0; } @@ -399,8 +399,8 @@ static void _reiserfs_free_block(struct reiserfs_transaction_handle *th, get_bit_address(s, block, &nr, &offset); if (nr >= reiserfs_bmap_count(s)) { - reiserfs_warning(s, "vs-4075", "block %lu is out of range", - block); + reiserfs_error(s, "vs-4075", "block %lu is out of range", + block); return; } @@ -412,8 +412,8 @@ static void _reiserfs_free_block(struct reiserfs_transaction_handle *th, /* clear bit for the given block in bit map */ if (!reiserfs_test_and_clear_le_bit(offset, bmbh->b_data)) { - reiserfs_warning(s, "vs-4080", - "block %lu: bit already cleared", block); + reiserfs_error(s, "vs-4080", + "block %lu: bit already cleared", block); } apbi[nr].free_count++; journal_mark_dirty(th, s, bmbh); @@ -440,7 +440,7 @@ void reiserfs_free_block(struct reiserfs_transaction_handle *th, return; if (block > sb_block_count(REISERFS_SB(s)->s_rs)) { - reiserfs_panic(th->t_super, "bitmap-4072", + reiserfs_error(th->t_super, "bitmap-4072", "Trying to free block outside file system " "boundaries (%lu > %lu)", block, sb_block_count(REISERFS_SB(s)->s_rs)); @@ -472,8 +472,8 @@ static void __discard_prealloc(struct reiserfs_transaction_handle *th, BUG_ON(!th->t_trans_id); #ifdef CONFIG_REISERFS_CHECK if (ei->i_prealloc_count < 0) - reiserfs_warning(th->t_super, "zam-4001", - "inode has negative prealloc blocks count."); + reiserfs_error(th->t_super, "zam-4001", + "inode has negative prealloc blocks count."); #endif while (ei->i_prealloc_count > 0) { reiserfs_free_prealloc_block(th, inode, ei->i_prealloc_block); @@ -509,9 +509,9 @@ void reiserfs_discard_all_prealloc(struct reiserfs_transaction_handle *th) i_prealloc_list); #ifdef CONFIG_REISERFS_CHECK if (!ei->i_prealloc_count) { - reiserfs_warning(th->t_super, "zam-4001", - "inode is in prealloc list but has " - "no preallocated blocks."); + reiserfs_error(th->t_super, "zam-4001", + "inode is in prealloc list but has " + "no preallocated blocks."); } #endif __discard_prealloc(th, ei); @@ -1213,7 +1213,9 @@ void reiserfs_cache_bitmap_metadata(struct super_block *sb, unsigned long *cur = (unsigned long *)(bh->b_data + bh->b_size); /* The first bit must ALWAYS be 1 */ - BUG_ON(!reiserfs_test_le_bit(0, (unsigned long *)bh->b_data)); + if (!reiserfs_test_le_bit(0, (unsigned long *)bh->b_data)) + reiserfs_error(sb, "reiserfs-2025", "bitmap block %lu is " + "corrupted: first bit must be 1", bh->b_blocknr); info->free_count = 0; diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 7ee0097004c0..fab0373ad6e3 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c @@ -841,12 +841,12 @@ int reiserfs_get_block(struct inode *inode, sector_t block, tail_offset); if (retval) { if (retval != -ENOSPC) - reiserfs_warning(inode->i_sb, - "clm-6004", - "convert tail failed " - "inode %lu, error %d", - inode->i_ino, - retval); + reiserfs_error(inode->i_sb, + "clm-6004", + "convert tail failed " + "inode %lu, error %d", + inode->i_ino, + retval); if (allocated_block_nr) { /* the bitmap, the super, and the stat data == 3 */ if (!th) @@ -1332,10 +1332,9 @@ void reiserfs_update_sd_size(struct reiserfs_transaction_handle *th, /* look for the object's stat data */ retval = search_item(inode->i_sb, &key, &path); if (retval == IO_ERROR) { - reiserfs_warning(inode->i_sb, "vs-13050", - "i/o failure occurred trying to " - "update %K stat data", - &key); + reiserfs_error(inode->i_sb, "vs-13050", + "i/o failure occurred trying to " + "update %K stat data", &key); return; } if (retval == ITEM_NOT_FOUND) { @@ -1424,9 +1423,9 @@ void reiserfs_read_locked_inode(struct inode *inode, /* look for the object's stat data */ retval = search_item(inode->i_sb, &key, &path_to_sd); if (retval == IO_ERROR) { - reiserfs_warning(inode->i_sb, "vs-13070", - "i/o failure occurred trying to find " - "stat data of %K", &key); + reiserfs_error(inode->i_sb, "vs-13070", + "i/o failure occurred trying to find " + "stat data of %K", &key); reiserfs_make_bad_inode(inode); return; } @@ -1678,8 +1677,8 @@ static int reiserfs_new_directory(struct reiserfs_transaction_handle *th, /* look for place in the tree for new item */ retval = search_item(sb, &key, path); if (retval == IO_ERROR) { - reiserfs_warning(sb, "vs-13080", - "i/o failure occurred creating new directory"); + reiserfs_error(sb, "vs-13080", + "i/o failure occurred creating new directory"); return -EIO; } if (retval == ITEM_FOUND) { @@ -1718,8 +1717,8 @@ static int reiserfs_new_symlink(struct reiserfs_transaction_handle *th, struct i /* look for place in the tree for new item */ retval = search_item(sb, &key, path); if (retval == IO_ERROR) { - reiserfs_warning(sb, "vs-13080", - "i/o failure occurred creating new symlink"); + reiserfs_error(sb, "vs-13080", + "i/o failure occurred creating new symlink"); return -EIO; } if (retval == ITEM_FOUND) { @@ -2043,10 +2042,8 @@ static int grab_tail_page(struct inode *p_s_inode, ** I've screwed up the code to find the buffer, or the code to ** call prepare_write */ - reiserfs_warning(p_s_inode->i_sb, "clm-6000", - "error reading block %lu on dev %s", - bh->b_blocknr, - reiserfs_bdevname(p_s_inode->i_sb)); + reiserfs_error(p_s_inode->i_sb, "clm-6000", + "error reading block %lu", bh->b_blocknr); error = -EIO; goto unlock; } @@ -2088,9 +2085,9 @@ int reiserfs_truncate_file(struct inode *p_s_inode, int update_timestamps) // and get_block_create_0 could not find a block to read in, // which is ok. if (error != -ENOENT) - reiserfs_warning(p_s_inode->i_sb, "clm-6001", - "grab_tail_page failed %d", - error); + reiserfs_error(p_s_inode->i_sb, "clm-6001", + "grab_tail_page failed %d", + error); page = NULL; bh = NULL; } diff --git a/fs/reiserfs/lbalance.c b/fs/reiserfs/lbalance.c index 67f1d1de213d..21a171ceba1d 100644 --- a/fs/reiserfs/lbalance.c +++ b/fs/reiserfs/lbalance.c @@ -1291,17 +1291,17 @@ void leaf_paste_entries(struct buffer_info *bi, prev = (i != 0) ? deh_location(&(deh[i - 1])) : 0; if (prev && prev <= deh_location(&(deh[i]))) - reiserfs_warning(NULL, "vs-10240", - "directory item (%h) " - "corrupted (prev %a, " - "cur(%d) %a)", - ih, deh + i - 1, i, deh + i); + reiserfs_error(sb_from_bi(bi), "vs-10240", + "directory item (%h) " + "corrupted (prev %a, " + "cur(%d) %a)", + ih, deh + i - 1, i, deh + i); if (next && next >= deh_location(&(deh[i]))) - reiserfs_warning(NULL, "vs-10250", - "directory item (%h) " - "corrupted (cur(%d) %a, " - "next %a)", - ih, i, deh + i, deh + i + 1); + reiserfs_error(sb_from_bi(bi), "vs-10250", + "directory item (%h) " + "corrupted (cur(%d) %a, " + "next %a)", + ih, i, deh + i, deh + i + 1); } } #endif diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index ef41cc882bd9..3ce3f8b1690d 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c @@ -120,8 +120,8 @@ int search_by_entry_key(struct super_block *sb, const struct cpu_key *key, switch (retval) { case ITEM_NOT_FOUND: if (!PATH_LAST_POSITION(path)) { - reiserfs_warning(sb, "vs-7000", "search_by_key " - "returned item position == 0"); + reiserfs_error(sb, "vs-7000", "search_by_key " + "returned item position == 0"); pathrelse(path); return IO_ERROR; } @@ -135,7 +135,7 @@ int search_by_entry_key(struct super_block *sb, const struct cpu_key *key, default: pathrelse(path); - reiserfs_warning(sb, "vs-7002", "no path to here"); + reiserfs_error(sb, "vs-7002", "no path to here"); return IO_ERROR; } @@ -298,7 +298,7 @@ static int reiserfs_find_entry(struct inode *dir, const char *name, int namelen, search_by_entry_key(dir->i_sb, &key_to_search, path_to_entry, de); if (retval == IO_ERROR) { - reiserfs_warning(dir->i_sb, "zam-7001", "io error"); + reiserfs_error(dir->i_sb, "zam-7001", "io error"); return IO_ERROR; } @@ -481,9 +481,9 @@ static int reiserfs_add_entry(struct reiserfs_transaction_handle *th, } if (retval != NAME_FOUND) { - reiserfs_warning(dir->i_sb, "zam-7002", - "reiserfs_find_entry() returned " - "unexpected value (%d)", retval); + reiserfs_error(dir->i_sb, "zam-7002", + "reiserfs_find_entry() returned " + "unexpected value (%d)", retval); } return -EEXIST; @@ -899,9 +899,9 @@ static int reiserfs_rmdir(struct inode *dir, struct dentry *dentry) goto end_rmdir; if (inode->i_nlink != 2 && inode->i_nlink != 1) - reiserfs_warning(inode->i_sb, "reiserfs-7040", - "empty directory has nlink != 2 (%d)", - inode->i_nlink); + reiserfs_error(inode->i_sb, "reiserfs-7040", + "empty directory has nlink != 2 (%d)", + inode->i_nlink); clear_nlink(inode); inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; @@ -1494,8 +1494,8 @@ static int reiserfs_rename(struct inode *old_dir, struct dentry *old_dentry, if (reiserfs_cut_from_item (&th, &old_entry_path, &(old_de.de_entry_key), old_dir, NULL, 0) < 0) - reiserfs_warning(old_dir->i_sb, "vs-7060", - "couldn't not cut old name. Fsck later?"); + reiserfs_error(old_dir->i_sb, "vs-7060", + "couldn't not cut old name. Fsck later?"); old_dir->i_size -= DEH_SIZE + old_de.de_entrylen; diff --git a/fs/reiserfs/objectid.c b/fs/reiserfs/objectid.c index 90e4e52f857b..d2d6b5650188 100644 --- a/fs/reiserfs/objectid.c +++ b/fs/reiserfs/objectid.c @@ -159,8 +159,8 @@ void reiserfs_release_objectid(struct reiserfs_transaction_handle *th, i += 2; } - reiserfs_warning(s, "vs-15011", "tried to free free object id (%lu)", - (long unsigned)objectid_to_release); + reiserfs_error(s, "vs-15011", "tried to free free object id (%lu)", + (long unsigned)objectid_to_release); } int reiserfs_convert_objectid_map_v1(struct super_block *s) diff --git a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c index 2de1e309124b..ec837a250a4f 100644 --- a/fs/reiserfs/stree.c +++ b/fs/reiserfs/stree.c @@ -720,9 +720,9 @@ int search_by_key(struct super_block *p_s_sb, const struct cpu_key *p_s_key, /* // make sure, that the node contents look like a node of // certain level if (!is_tree_node(p_s_bh, expected_level)) { - reiserfs_warning(p_s_sb, "vs-5150", - "invalid format found in block %ld. " - "Fsck?", p_s_bh->b_blocknr); + reiserfs_error(p_s_sb, "vs-5150", + "invalid format found in block %ld. " + "Fsck?", p_s_bh->b_blocknr); pathrelse(p_s_search_path); return IO_ERROR; } @@ -1336,9 +1336,9 @@ void reiserfs_delete_solid_item(struct reiserfs_transaction_handle *th, while (1) { retval = search_item(th->t_super, &cpu_key, &path); if (retval == IO_ERROR) { - reiserfs_warning(th->t_super, "vs-5350", - "i/o failure occurred trying " - "to delete %K", &cpu_key); + reiserfs_error(th->t_super, "vs-5350", + "i/o failure occurred trying " + "to delete %K", &cpu_key); break; } if (retval != ITEM_FOUND) { @@ -1737,7 +1737,7 @@ static void truncate_directory(struct reiserfs_transaction_handle *th, { BUG_ON(!th->t_trans_id); if (inode->i_nlink) - reiserfs_warning(inode->i_sb, "vs-5655", "link count != 0"); + reiserfs_error(inode->i_sb, "vs-5655", "link count != 0"); set_le_key_k_offset(KEY_FORMAT_3_5, INODE_PKEY(inode), DOT_OFFSET); set_le_key_k_type(KEY_FORMAT_3_5, INODE_PKEY(inode), TYPE_DIRENTRY); @@ -1790,16 +1790,16 @@ int reiserfs_do_truncate(struct reiserfs_transaction_handle *th, struct inode *p search_for_position_by_key(p_s_inode->i_sb, &s_item_key, &s_search_path); if (retval == IO_ERROR) { - reiserfs_warning(p_s_inode->i_sb, "vs-5657", - "i/o failure occurred trying to truncate %K", - &s_item_key); + reiserfs_error(p_s_inode->i_sb, "vs-5657", + "i/o failure occurred trying to truncate %K", + &s_item_key); err = -EIO; goto out; } if (retval == POSITION_FOUND || retval == FILE_NOT_FOUND) { - reiserfs_warning(p_s_inode->i_sb, "PAP-5660", - "wrong result %d of search for %K", retval, - &s_item_key); + reiserfs_error(p_s_inode->i_sb, "PAP-5660", + "wrong result %d of search for %K", retval, + &s_item_key); err = -EIO; goto out; diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index bfc276c8e978..fc7cb4661ee0 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -195,9 +195,8 @@ static int finish_unfinished(struct super_block *s) while (!retval) { retval = search_item(s, &max_cpu_key, &path); if (retval != ITEM_NOT_FOUND) { - reiserfs_warning(s, "vs-2140", - "search_by_key returned %d", - retval); + reiserfs_error(s, "vs-2140", + "search_by_key returned %d", retval); break; } @@ -378,9 +377,9 @@ void add_save_link(struct reiserfs_transaction_handle *th, retval = search_item(inode->i_sb, &key, &path); if (retval != ITEM_NOT_FOUND) { if (retval != -ENOSPC) - reiserfs_warning(inode->i_sb, "vs-2100", - "search_by_key (%K) returned %d", &key, - retval); + reiserfs_error(inode->i_sb, "vs-2100", + "search_by_key (%K) returned %d", &key, + retval); pathrelse(&path); return; } @@ -393,8 +392,8 @@ void add_save_link(struct reiserfs_transaction_handle *th, reiserfs_insert_item(th, &path, &key, &ih, NULL, (char *)&link); if (retval) { if (retval != -ENOSPC) - reiserfs_warning(inode->i_sb, "vs-2120", - "insert_item returned %d", retval); + reiserfs_error(inode->i_sb, "vs-2120", + "insert_item returned %d", retval); } else { if (truncate) REISERFS_I(inode)->i_flags |= diff --git a/fs/reiserfs/tail_conversion.c b/fs/reiserfs/tail_conversion.c index f8449cb74b53..083f74435f65 100644 --- a/fs/reiserfs/tail_conversion.c +++ b/fs/reiserfs/tail_conversion.c @@ -48,9 +48,9 @@ int direct2indirect(struct reiserfs_transaction_handle *th, struct inode *inode, // FIXME: we could avoid this if (search_for_position_by_key(sb, &end_key, path) == POSITION_FOUND) { - reiserfs_warning(sb, "PAP-14030", - "pasted or inserted byte exists in " - "the tree %K. Use fsck to repair.", &end_key); + reiserfs_error(sb, "PAP-14030", + "pasted or inserted byte exists in " + "the tree %K. Use fsck to repair.", &end_key); pathrelse(path); return -EIO; } diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index d14f5c2c0e4a..bab77fe5f177 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c @@ -259,8 +259,8 @@ static int __xattr_readdir(struct inode *inode, void *dirent, filldir_t filldir) ih = de.de_ih; if (!is_direntry_le_ih(ih)) { - reiserfs_warning(inode->i_sb, "jdm-20000", - "not direntry %h", ih); + reiserfs_error(inode->i_sb, "jdm-20000", + "not direntry %h", ih); break; } copy_item_head(&tmp_ih, ih); @@ -653,15 +653,14 @@ __reiserfs_xattr_del(struct dentry *xadir, const char *name, int namelen) goto out_file; if (!is_reiserfs_priv_object(dentry->d_inode)) { - reiserfs_warning(dir->i_sb, "jdm-20003", - "OID %08x [%.*s/%.*s] doesn't have " - "priv flag set [parent is %sset].", - le32_to_cpu(INODE_PKEY(dentry->d_inode)-> - k_objectid), xadir->d_name.len, - xadir->d_name.name, namelen, name, - is_reiserfs_priv_object(xadir-> - d_inode) ? "" : - "not "); + reiserfs_error(dir->i_sb, "jdm-20003", + "OID %08x [%.*s/%.*s] doesn't have " + "priv flag set [parent is %sset].", + le32_to_cpu(INODE_PKEY(dentry->d_inode)-> + k_objectid), xadir->d_name.len, + xadir->d_name.name, namelen, name, + is_reiserfs_priv_object(xadir->d_inode) ? "" : + "not "); dput(dentry); return -EIO; } -- cgit v1.2.3 From f437c529e3cd4853c1edff6fe3b191ad32304e8f Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Mon, 30 Mar 2009 14:02:29 -0400 Subject: reiserfs: small variable cleanup This patch removes the xinode and mapping variables from reiserfs_xattr_{get,set}. Signed-off-by: Jeff Mahoney Signed-off-by: Linus Torvalds --- fs/reiserfs/xattr.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'fs/reiserfs/xattr.c') diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index bab77fe5f177..59b0850e885f 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c @@ -420,10 +420,8 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, struct dentry *dentry; struct page *page; char *data; - struct address_space *mapping; size_t file_pos = 0; size_t buffer_pos = 0; - struct inode *xinode; struct iattr newattrs; __u32 xahash = 0; @@ -441,11 +439,10 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, goto out; } - xinode = dentry->d_inode; REISERFS_I(inode)->i_flags |= i_has_xattr_dir; /* we need to copy it off.. */ - if (xinode->i_nlink > 1) { + if (dentry->d_inode->i_nlink > 1) { dput(dentry); err = reiserfs_xattr_del(inode, name); if (err < 0) @@ -459,12 +456,11 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, /* Resize it so we're ok to write there */ newattrs.ia_size = buffer_size; newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; - mutex_lock_nested(&xinode->i_mutex, I_MUTEX_XATTR); + mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_XATTR); err = notify_change(dentry, &newattrs); if (err) goto out_filp; - mapping = xinode->i_mapping; while (buffer_pos < buffer_size || buffer_pos == 0) { size_t chunk; size_t skip = 0; @@ -474,7 +470,8 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, else chunk = buffer_size - buffer_pos; - page = reiserfs_get_page(xinode, file_pos >> PAGE_CACHE_SHIFT); + page = reiserfs_get_page(dentry->d_inode, + file_pos >> PAGE_CACHE_SHIFT); if (IS_ERR(page)) { err = PTR_ERR(page); goto out_filp; @@ -521,7 +518,7 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, } out_filp: - mutex_unlock(&xinode->i_mutex); + mutex_unlock(&dentry->d_inode->i_mutex); dput(dentry); out: @@ -541,7 +538,6 @@ reiserfs_xattr_get(const struct inode *inode, const char *name, void *buffer, size_t file_pos = 0; size_t buffer_pos = 0; struct page *page; - struct inode *xinode; __u32 hash = 0; if (name == NULL) @@ -558,8 +554,7 @@ reiserfs_xattr_get(const struct inode *inode, const char *name, void *buffer, goto out; } - xinode = dentry->d_inode; - isize = xinode->i_size; + isize = i_size_read(dentry->d_inode); REISERFS_I(inode)->i_flags |= i_has_xattr_dir; /* Just return the size needed */ @@ -582,7 +577,8 @@ reiserfs_xattr_get(const struct inode *inode, const char *name, void *buffer, else chunk = isize - file_pos; - page = reiserfs_get_page(xinode, file_pos >> PAGE_CACHE_SHIFT); + page = reiserfs_get_page(dentry->d_inode, + file_pos >> PAGE_CACHE_SHIFT); if (IS_ERR(page)) { err = PTR_ERR(page); goto out_dput; -- cgit v1.2.3 From ec6ea56b2f1d3811815e53131e85fd1fc9b51873 Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Mon, 30 Mar 2009 14:02:30 -0400 Subject: reiserfs: xattr reiserfs_get_page takes offset instead of index This patch changes reiserfs_get_page to take an offset rather than an index since no callers calculate the index differently. Signed-off-by: Jeff Mahoney Signed-off-by: Linus Torvalds --- fs/reiserfs/xattr.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'fs/reiserfs/xattr.c') diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index 59b0850e885f..132d901da08f 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c @@ -376,14 +376,14 @@ static inline void reiserfs_put_page(struct page *page) page_cache_release(page); } -static struct page *reiserfs_get_page(struct inode *dir, unsigned long n) +static struct page *reiserfs_get_page(struct inode *dir, size_t n) { struct address_space *mapping = dir->i_mapping; struct page *page; /* We can deadlock if we try to free dentries, and an unlink/rmdir has just occured - GFP_NOFS avoids this */ mapping_set_gfp_mask(mapping, GFP_NOFS); - page = read_mapping_page(mapping, n, NULL); + page = read_mapping_page(mapping, n >> PAGE_CACHE_SHIFT, NULL); if (!IS_ERR(page)) { kmap(page); if (PageError(page)) @@ -470,8 +470,7 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, else chunk = buffer_size - buffer_pos; - page = reiserfs_get_page(dentry->d_inode, - file_pos >> PAGE_CACHE_SHIFT); + page = reiserfs_get_page(dentry->d_inode, file_pos); if (IS_ERR(page)) { err = PTR_ERR(page); goto out_filp; @@ -577,8 +576,7 @@ reiserfs_xattr_get(const struct inode *inode, const char *name, void *buffer, else chunk = isize - file_pos; - page = reiserfs_get_page(dentry->d_inode, - file_pos >> PAGE_CACHE_SHIFT); + page = reiserfs_get_page(dentry->d_inode, file_pos); if (IS_ERR(page)) { err = PTR_ERR(page); goto out_dput; -- cgit v1.2.3 From 010f5a21a323e7383e067009a7785462883fe5ea Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Mon, 30 Mar 2009 14:02:31 -0400 Subject: reiserfs: remove link detection code Early in the reiserfs xattr development, there was a plan to use hardlinks to save disk space for identical xattrs. That code never materialized and isn't going to, so this patch removes the detection code. Signed-off-by: Jeff Mahoney Signed-off-by: Linus Torvalds --- fs/reiserfs/xattr.c | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'fs/reiserfs/xattr.c') diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index 132d901da08f..3e9e82ca3ba2 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c @@ -432,7 +432,6 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, if (buffer && buffer_size) xahash = xattr_hash(buffer, buffer_size); - open_file: dentry = get_xa_file_dentry(inode, name, flags); if (IS_ERR(dentry)) { err = PTR_ERR(dentry); @@ -441,18 +440,6 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, REISERFS_I(inode)->i_flags |= i_has_xattr_dir; - /* we need to copy it off.. */ - if (dentry->d_inode->i_nlink > 1) { - dput(dentry); - err = reiserfs_xattr_del(inode, name); - if (err < 0) - goto out; - /* We just killed the old one, we're not replacing anymore */ - if (flags & XATTR_REPLACE) - flags &= ~XATTR_REPLACE; - goto open_file; - } - /* Resize it so we're ok to write there */ newattrs.ia_size = buffer_size; newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; -- cgit v1.2.3 From 6dfede696391133eadd7ce90b61c9573ee6e5a90 Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Mon, 30 Mar 2009 14:02:32 -0400 Subject: reiserfs: remove IS_PRIVATE helpers There are a number of helper functions for marking a reiserfs inode private that were leftover from reiserfs did its own thing wrt to private inodes. S_PRIVATE has been in the kernel for some time, so this patch removes the helpers and uses IS_PRIVATE instead. Signed-off-by: Jeff Mahoney Signed-off-by: Linus Torvalds --- fs/reiserfs/inode.c | 5 ++--- fs/reiserfs/namei.c | 7 ++++--- fs/reiserfs/xattr.c | 14 ++++++-------- fs/reiserfs/xattr_acl.c | 6 +++--- fs/reiserfs/xattr_security.c | 8 ++++---- fs/reiserfs/xattr_trusted.c | 8 ++++---- include/linux/reiserfs_xattr.h | 8 -------- 7 files changed, 23 insertions(+), 33 deletions(-) (limited to 'fs/reiserfs/xattr.c') diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index fab0373ad6e3..cd42a8658086 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c @@ -1927,9 +1927,8 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, reiserfs_warning(inode->i_sb, "jdm-13090", "ACLs aren't enabled in the fs, " "but vfs thinks they are!"); - } else if (is_reiserfs_priv_object(dir)) { - reiserfs_mark_inode_private(inode); - } + } else if (IS_PRIVATE(dir)) + inode->i_flags |= S_PRIVATE; reiserfs_update_sd(th, inode); reiserfs_check_path(&path_to_key); diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index 3ce3f8b1690d..c8430f1c824f 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c @@ -358,9 +358,10 @@ static struct dentry *reiserfs_lookup(struct inode *dir, struct dentry *dentry, return ERR_PTR(-EACCES); } - /* Propogate the priv_object flag so we know we're in the priv tree */ - if (is_reiserfs_priv_object(dir)) - reiserfs_mark_inode_private(inode); + /* Propagate the private flag so we know we're + * in the priv tree */ + if (IS_PRIVATE(dir)) + inode->i_flags |= S_PRIVATE; } reiserfs_write_unlock(dir->i_sb); if (retval == IO_ERROR) { diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index 3e9e82ca3ba2..c5fc207e529c 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c @@ -633,14 +633,14 @@ __reiserfs_xattr_del(struct dentry *xadir, const char *name, int namelen) if (S_ISDIR(dentry->d_inode->i_mode)) goto out_file; - if (!is_reiserfs_priv_object(dentry->d_inode)) { + if (!IS_PRIVATE(dentry->d_inode)) { reiserfs_error(dir->i_sb, "jdm-20003", "OID %08x [%.*s/%.*s] doesn't have " "priv flag set [parent is %sset].", le32_to_cpu(INODE_PKEY(dentry->d_inode)-> k_objectid), xadir->d_name.len, xadir->d_name.name, namelen, name, - is_reiserfs_priv_object(xadir->d_inode) ? "" : + IS_PRIVATE(xadir->d_inode) ? "" : "not "); dput(dentry); return -EIO; @@ -701,8 +701,7 @@ int reiserfs_delete_xattrs(struct inode *inode) int err = 0; /* Skip out, an xattr has no xattrs associated with it */ - if (is_reiserfs_priv_object(inode) || - get_inode_sd_version(inode) == STAT_DATA_V1 || + if (IS_PRIVATE(inode) || get_inode_sd_version(inode) == STAT_DATA_V1 || !reiserfs_xattrs(inode->i_sb)) { return 0; } @@ -786,8 +785,7 @@ int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs) unsigned int ia_valid = attrs->ia_valid; /* Skip out, an xattr has no xattrs associated with it */ - if (is_reiserfs_priv_object(inode) || - get_inode_sd_version(inode) == STAT_DATA_V1 || + if (IS_PRIVATE(inode) || get_inode_sd_version(inode) == STAT_DATA_V1 || !reiserfs_xattrs(inode->i_sb)) { return 0; } @@ -1178,7 +1176,7 @@ int reiserfs_xattr_init(struct super_block *s, int mount_flags) if (!err && dentry) { s->s_root->d_op = &xattr_lookup_poison_ops; - reiserfs_mark_inode_private(dentry->d_inode); + dentry->d_inode->i_flags |= S_PRIVATE; REISERFS_SB(s)->priv_root = dentry; } else if (!(mount_flags & MS_RDONLY)) { /* xattrs are unavailable */ /* If we're read-only it just means that the dir hasn't been @@ -1239,7 +1237,7 @@ int reiserfs_permission(struct inode *inode, int mask) * We don't do permission checks on the internal objects. * Permissions are determined by the "owning" object. */ - if (is_reiserfs_priv_object(inode)) + if (IS_PRIVATE(inode)) return 0; /* diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c index b7e4fa4539de..9128e4d5ba64 100644 --- a/fs/reiserfs/xattr_acl.c +++ b/fs/reiserfs/xattr_acl.c @@ -335,8 +335,8 @@ reiserfs_inherit_default_acl(struct inode *dir, struct dentry *dentry, /* Don't apply ACLs to objects in the .reiserfs_priv tree.. This * would be useless since permissions are ignored, and a pain because * it introduces locking cycles */ - if (is_reiserfs_priv_object(dir)) { - reiserfs_mark_inode_private(inode); + if (IS_PRIVATE(dir)) { + inode->i_flags |= S_PRIVATE; goto apply_umask; } @@ -401,7 +401,7 @@ reiserfs_inherit_default_acl(struct inode *dir, struct dentry *dentry, int reiserfs_cache_default_acl(struct inode *inode) { int ret = 0; - if (reiserfs_posixacl(inode->i_sb) && !is_reiserfs_priv_object(inode)) { + if (reiserfs_posixacl(inode->i_sb) && !IS_PRIVATE(inode)) { struct posix_acl *acl; reiserfs_read_lock_xattr_i(inode); reiserfs_read_lock_xattrs(inode->i_sb); diff --git a/fs/reiserfs/xattr_security.c b/fs/reiserfs/xattr_security.c index 056008db1377..1958b361c35d 100644 --- a/fs/reiserfs/xattr_security.c +++ b/fs/reiserfs/xattr_security.c @@ -12,7 +12,7 @@ security_get(struct inode *inode, const char *name, void *buffer, size_t size) if (strlen(name) < sizeof(XATTR_SECURITY_PREFIX)) return -EINVAL; - if (is_reiserfs_priv_object(inode)) + if (IS_PRIVATE(inode)) return -EPERM; return reiserfs_xattr_get(inode, name, buffer, size); @@ -25,7 +25,7 @@ security_set(struct inode *inode, const char *name, const void *buffer, if (strlen(name) < sizeof(XATTR_SECURITY_PREFIX)) return -EINVAL; - if (is_reiserfs_priv_object(inode)) + if (IS_PRIVATE(inode)) return -EPERM; return reiserfs_xattr_set(inode, name, buffer, size, flags); @@ -36,7 +36,7 @@ static int security_del(struct inode *inode, const char *name) if (strlen(name) < sizeof(XATTR_SECURITY_PREFIX)) return -EINVAL; - if (is_reiserfs_priv_object(inode)) + if (IS_PRIVATE(inode)) return -EPERM; return 0; @@ -47,7 +47,7 @@ security_list(struct inode *inode, const char *name, int namelen, char *out) { int len = namelen; - if (is_reiserfs_priv_object(inode)) + if (IS_PRIVATE(inode)) return 0; if (out) diff --git a/fs/reiserfs/xattr_trusted.c b/fs/reiserfs/xattr_trusted.c index 60abe2bb1f98..076ad388d489 100644 --- a/fs/reiserfs/xattr_trusted.c +++ b/fs/reiserfs/xattr_trusted.c @@ -16,7 +16,7 @@ trusted_get(struct inode *inode, const char *name, void *buffer, size_t size) if (!reiserfs_xattrs(inode->i_sb)) return -EOPNOTSUPP; - if (!(capable(CAP_SYS_ADMIN) || is_reiserfs_priv_object(inode))) + if (!(capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode))) return -EPERM; return reiserfs_xattr_get(inode, name, buffer, size); @@ -32,7 +32,7 @@ trusted_set(struct inode *inode, const char *name, const void *buffer, if (!reiserfs_xattrs(inode->i_sb)) return -EOPNOTSUPP; - if (!(capable(CAP_SYS_ADMIN) || is_reiserfs_priv_object(inode))) + if (!(capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode))) return -EPERM; return reiserfs_xattr_set(inode, name, buffer, size, flags); @@ -46,7 +46,7 @@ static int trusted_del(struct inode *inode, const char *name) if (!reiserfs_xattrs(inode->i_sb)) return -EOPNOTSUPP; - if (!(capable(CAP_SYS_ADMIN) || is_reiserfs_priv_object(inode))) + if (!(capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode))) return -EPERM; return 0; @@ -60,7 +60,7 @@ trusted_list(struct inode *inode, const char *name, int namelen, char *out) if (!reiserfs_xattrs(inode->i_sb)) return 0; - if (!(capable(CAP_SYS_ADMIN) || is_reiserfs_priv_object(inode))) + if (!(capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode))) return 0; if (out) diff --git a/include/linux/reiserfs_xattr.h b/include/linux/reiserfs_xattr.h index af135ae895db..58f32ba7f5a0 100644 --- a/include/linux/reiserfs_xattr.h +++ b/include/linux/reiserfs_xattr.h @@ -44,7 +44,6 @@ struct reiserfs_xattr_handler { }; #ifdef CONFIG_REISERFS_FS_XATTR -#define is_reiserfs_priv_object(inode) IS_PRIVATE(inode) #define has_xattr_dir(inode) (REISERFS_I(inode)->i_flags & i_has_xattr_dir) ssize_t reiserfs_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t size); @@ -104,11 +103,6 @@ static inline void reiserfs_read_unlock_xattr_i(struct inode *inode) up_read(&REISERFS_I(inode)->xattr_sem); } -static inline void reiserfs_mark_inode_private(struct inode *inode) -{ - inode->i_flags |= S_PRIVATE; -} - static inline void reiserfs_init_xattr_rwsem(struct inode *inode) { init_rwsem(&REISERFS_I(inode)->xattr_sem); @@ -116,8 +110,6 @@ static inline void reiserfs_init_xattr_rwsem(struct inode *inode) #else -#define is_reiserfs_priv_object(inode) 0 -#define reiserfs_mark_inode_private(inode) do {;} while(0) #define reiserfs_getxattr NULL #define reiserfs_setxattr NULL #define reiserfs_listxattr NULL -- cgit v1.2.3 From a72bdb1cd244725ff47b3a29662e2cb820d8c60f Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Mon, 30 Mar 2009 14:02:33 -0400 Subject: reiserfs: Clean up xattrs when REISERFS_FS_XATTR is unset The current reiserfs xattr implementation will not clean up old xattr files if files are deleted when REISERFS_FS_XATTR is unset. This results in inaccessible lost files, wasting space. This patch compiles in basic xattr knowledge, such as how to delete them and change ownership for quota tracking. If the file system has never used xattrs, then the operation is quite fast: it returns immediately when it sees there is no .reiserfs_priv directory. Signed-off-by: Jeff Mahoney Signed-off-by: Linus Torvalds --- fs/reiserfs/Makefile | 4 +- fs/reiserfs/xattr.c | 801 +++++++++++++++++++++-------------------- include/linux/reiserfs_fs_sb.h | 2 +- include/linux/reiserfs_xattr.h | 29 +- 4 files changed, 423 insertions(+), 413 deletions(-) (limited to 'fs/reiserfs/xattr.c') diff --git a/fs/reiserfs/Makefile b/fs/reiserfs/Makefile index 0eb7ac080484..7c5ab6330dd6 100644 --- a/fs/reiserfs/Makefile +++ b/fs/reiserfs/Makefile @@ -7,10 +7,10 @@ obj-$(CONFIG_REISERFS_FS) += reiserfs.o reiserfs-objs := bitmap.o do_balan.o namei.o inode.o file.o dir.o fix_node.o \ super.o prints.o objectid.o lbalance.o ibalance.o stree.o \ hashes.o tail_conversion.o journal.o resize.o \ - item_ops.o ioctl.o procfs.o + item_ops.o ioctl.o procfs.o xattr.o ifeq ($(CONFIG_REISERFS_FS_XATTR),y) -reiserfs-objs += xattr.o xattr_user.o xattr_trusted.o +reiserfs-objs += xattr_user.o xattr_trusted.o endif ifeq ($(CONFIG_REISERFS_FS_SECURITY),y) diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index c5fc207e529c..f9bcdd5750f7 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c @@ -50,9 +50,6 @@ #define PRIVROOT_NAME ".reiserfs_priv" #define XAROOT_NAME "xattrs" -static struct reiserfs_xattr_handler *find_xattr_handler_prefix(const char - *prefix); - /* Returns the dentry referring to the root of the extended attribute * directory tree. If it has already been retrieved, it is used. If it * hasn't been created and the flags indicate creation is allowed, we @@ -143,60 +140,6 @@ static struct dentry *open_xa_dir(const struct inode *inode, int flags) return xadir; } -/* Returns a dentry corresponding to a specific extended attribute file - * for the inode. If flags allow, the file is created. Otherwise, a - * valid or negative dentry, or an error is returned. */ -static struct dentry *get_xa_file_dentry(const struct inode *inode, - const char *name, int flags) -{ - struct dentry *xadir, *xafile; - int err = 0; - - xadir = open_xa_dir(inode, flags); - if (IS_ERR(xadir)) { - return ERR_CAST(xadir); - } else if (!xadir->d_inode) { - dput(xadir); - return ERR_PTR(-ENODATA); - } - - xafile = lookup_one_len(name, xadir, strlen(name)); - if (IS_ERR(xafile)) { - dput(xadir); - return ERR_CAST(xafile); - } - - if (xafile->d_inode) { /* file exists */ - if (flags & XATTR_CREATE) { - err = -EEXIST; - dput(xafile); - goto out; - } - } else if (flags & XATTR_REPLACE || flags & FL_READONLY) { - goto out; - } else { - /* inode->i_mutex is down, so nothing else can try to create - * the same xattr */ - err = xadir->d_inode->i_op->create(xadir->d_inode, xafile, - 0700 | S_IFREG, NULL); - - if (err) { - dput(xafile); - goto out; - } - } - - out: - dput(xadir); - if (err) - xafile = ERR_PTR(err); - else if (!xafile->d_inode) { - dput(xafile); - xafile = ERR_PTR(-ENODATA); - } - return xafile; -} - /* * this is very similar to fs/reiserfs/dir.c:reiserfs_readdir, but * we need to drop the path before calling the filldir struct. That @@ -369,6 +312,251 @@ int xattr_readdir(struct inode *inode, filldir_t filler, void *buf) return res; } +static int +__reiserfs_xattr_del(struct dentry *xadir, const char *name, int namelen) +{ + struct dentry *dentry; + struct inode *dir = xadir->d_inode; + int err = 0; + + dentry = lookup_one_len(name, xadir, namelen); + if (IS_ERR(dentry)) { + err = PTR_ERR(dentry); + goto out; + } else if (!dentry->d_inode) { + err = -ENODATA; + goto out_file; + } + + /* Skip directories.. */ + if (S_ISDIR(dentry->d_inode->i_mode)) + goto out_file; + + if (!IS_PRIVATE(dentry->d_inode)) { + reiserfs_error(dir->i_sb, "jdm-20003", + "OID %08x [%.*s/%.*s] doesn't have " + "priv flag set [parent is %sset].", + le32_to_cpu(INODE_PKEY(dentry->d_inode)-> + k_objectid), xadir->d_name.len, + xadir->d_name.name, namelen, name, + IS_PRIVATE(xadir->d_inode) ? "" : + "not "); + dput(dentry); + return -EIO; + } + + err = dir->i_op->unlink(dir, dentry); + if (!err) + d_delete(dentry); + +out_file: + dput(dentry); + +out: + return err; +} + +/* The following are side effects of other operations that aren't explicitly + * modifying extended attributes. This includes operations such as permissions + * or ownership changes, object deletions, etc. */ + +static int +reiserfs_delete_xattrs_filler(void *buf, const char *name, int namelen, + loff_t offset, u64 ino, unsigned int d_type) +{ + struct dentry *xadir = (struct dentry *)buf; + + return __reiserfs_xattr_del(xadir, name, namelen); + +} + +/* This is called w/ inode->i_mutex downed */ +int reiserfs_delete_xattrs(struct inode *inode) +{ + struct dentry *dir, *root; + int err = 0; + + /* Skip out, an xattr has no xattrs associated with it */ + if (IS_PRIVATE(inode) || get_inode_sd_version(inode) == STAT_DATA_V1) + return 0; + + reiserfs_read_lock_xattrs(inode->i_sb); + dir = open_xa_dir(inode, FL_READONLY); + reiserfs_read_unlock_xattrs(inode->i_sb); + if (IS_ERR(dir)) { + err = PTR_ERR(dir); + goto out; + } else if (!dir->d_inode) { + dput(dir); + return 0; + } + + lock_kernel(); + err = xattr_readdir(dir->d_inode, reiserfs_delete_xattrs_filler, dir); + if (err) { + unlock_kernel(); + goto out_dir; + } + + /* Leftovers besides . and .. -- that's not good. */ + if (dir->d_inode->i_nlink <= 2) { + root = get_xa_root(inode->i_sb, XATTR_REPLACE); + reiserfs_write_lock_xattrs(inode->i_sb); + err = vfs_rmdir(root->d_inode, dir); + reiserfs_write_unlock_xattrs(inode->i_sb); + dput(root); + } else { + reiserfs_warning(inode->i_sb, "jdm-20006", + "Couldn't remove all entries in directory"); + } + unlock_kernel(); + +out_dir: + dput(dir); + +out: + if (!err) + REISERFS_I(inode)->i_flags = + REISERFS_I(inode)->i_flags & ~i_has_xattr_dir; + return err; +} + +struct reiserfs_chown_buf { + struct inode *inode; + struct dentry *xadir; + struct iattr *attrs; +}; + +/* XXX: If there is a better way to do this, I'd love to hear about it */ +static int +reiserfs_chown_xattrs_filler(void *buf, const char *name, int namelen, + loff_t offset, u64 ino, unsigned int d_type) +{ + struct reiserfs_chown_buf *chown_buf = (struct reiserfs_chown_buf *)buf; + struct dentry *xafile, *xadir = chown_buf->xadir; + struct iattr *attrs = chown_buf->attrs; + int err = 0; + + xafile = lookup_one_len(name, xadir, namelen); + if (IS_ERR(xafile)) + return PTR_ERR(xafile); + else if (!xafile->d_inode) { + dput(xafile); + return -ENODATA; + } + + if (!S_ISDIR(xafile->d_inode->i_mode)) + err = notify_change(xafile, attrs); + dput(xafile); + + return err; +} + +int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs) +{ + struct dentry *dir; + int err = 0; + struct reiserfs_chown_buf buf; + unsigned int ia_valid = attrs->ia_valid; + + /* Skip out, an xattr has no xattrs associated with it */ + if (IS_PRIVATE(inode) || get_inode_sd_version(inode) == STAT_DATA_V1) + return 0; + + reiserfs_read_lock_xattrs(inode->i_sb); + dir = open_xa_dir(inode, FL_READONLY); + reiserfs_read_unlock_xattrs(inode->i_sb); + if (IS_ERR(dir)) { + if (PTR_ERR(dir) != -ENODATA) + err = PTR_ERR(dir); + goto out; + } else if (!dir->d_inode) { + dput(dir); + goto out; + } + + lock_kernel(); + + attrs->ia_valid &= (ATTR_UID | ATTR_GID | ATTR_CTIME); + buf.xadir = dir; + buf.attrs = attrs; + buf.inode = inode; + + err = xattr_readdir(dir->d_inode, reiserfs_chown_xattrs_filler, &buf); + if (err) { + unlock_kernel(); + goto out_dir; + } + + err = notify_change(dir, attrs); + unlock_kernel(); + +out_dir: + dput(dir); + +out: + attrs->ia_valid = ia_valid; + return err; +} + +#ifdef CONFIG_REISERFS_FS_XATTR +static struct reiserfs_xattr_handler *find_xattr_handler_prefix(const char + *prefix); + +/* Returns a dentry corresponding to a specific extended attribute file + * for the inode. If flags allow, the file is created. Otherwise, a + * valid or negative dentry, or an error is returned. */ +static struct dentry *get_xa_file_dentry(const struct inode *inode, + const char *name, int flags) +{ + struct dentry *xadir, *xafile; + int err = 0; + + xadir = open_xa_dir(inode, flags); + if (IS_ERR(xadir)) { + return ERR_CAST(xadir); + } else if (xadir && !xadir->d_inode) { + dput(xadir); + return ERR_PTR(-ENODATA); + } + + xafile = lookup_one_len(name, xadir, strlen(name)); + if (IS_ERR(xafile)) { + dput(xadir); + return ERR_CAST(xafile); + } + + if (xafile->d_inode) { /* file exists */ + if (flags & XATTR_CREATE) { + err = -EEXIST; + dput(xafile); + goto out; + } + } else if (flags & XATTR_REPLACE || flags & FL_READONLY) { + goto out; + } else { + /* inode->i_mutex is down, so nothing else can try to create + * the same xattr */ + err = xadir->d_inode->i_op->create(xadir->d_inode, xafile, + 0700 | S_IFREG, NULL); + + if (err) { + dput(xafile); + goto out; + } + } + +out: + dput(xadir); + if (err) + xafile = ERR_PTR(err); + else if (!xafile->d_inode) { + dput(xafile); + xafile = ERR_PTR(-ENODATA); + } + return xafile; +} + /* Internal operations on file data */ static inline void reiserfs_put_page(struct page *page) { @@ -554,274 +742,85 @@ reiserfs_xattr_get(const struct inode *inode, const char *name, void *buffer, goto out_dput; } - while (file_pos < isize) { - size_t chunk; - char *data; - size_t skip = 0; - if (isize - file_pos > PAGE_CACHE_SIZE) - chunk = PAGE_CACHE_SIZE; - else - chunk = isize - file_pos; - - page = reiserfs_get_page(dentry->d_inode, file_pos); - if (IS_ERR(page)) { - err = PTR_ERR(page); - goto out_dput; - } - - lock_page(page); - data = page_address(page); - if (file_pos == 0) { - struct reiserfs_xattr_header *rxh = - (struct reiserfs_xattr_header *)data; - skip = file_pos = sizeof(struct reiserfs_xattr_header); - chunk -= skip; - /* Magic doesn't match up.. */ - if (rxh->h_magic != cpu_to_le32(REISERFS_XATTR_MAGIC)) { - unlock_page(page); - reiserfs_put_page(page); - reiserfs_warning(inode->i_sb, "jdm-20001", - "Invalid magic for xattr (%s) " - "associated with %k", name, - INODE_PKEY(inode)); - err = -EIO; - goto out_dput; - } - hash = le32_to_cpu(rxh->h_hash); - } - memcpy(buffer + buffer_pos, data + skip, chunk); - unlock_page(page); - reiserfs_put_page(page); - file_pos += chunk; - buffer_pos += chunk; - skip = 0; - } - err = isize - sizeof(struct reiserfs_xattr_header); - - if (xattr_hash(buffer, isize - sizeof(struct reiserfs_xattr_header)) != - hash) { - reiserfs_warning(inode->i_sb, "jdm-20002", - "Invalid hash for xattr (%s) associated " - "with %k", name, INODE_PKEY(inode)); - err = -EIO; - } - - out_dput: - dput(dentry); - - out: - return err; -} - -static int -__reiserfs_xattr_del(struct dentry *xadir, const char *name, int namelen) -{ - struct dentry *dentry; - struct inode *dir = xadir->d_inode; - int err = 0; - - dentry = lookup_one_len(name, xadir, namelen); - if (IS_ERR(dentry)) { - err = PTR_ERR(dentry); - goto out; - } else if (!dentry->d_inode) { - err = -ENODATA; - goto out_file; - } - - /* Skip directories.. */ - if (S_ISDIR(dentry->d_inode->i_mode)) - goto out_file; - - if (!IS_PRIVATE(dentry->d_inode)) { - reiserfs_error(dir->i_sb, "jdm-20003", - "OID %08x [%.*s/%.*s] doesn't have " - "priv flag set [parent is %sset].", - le32_to_cpu(INODE_PKEY(dentry->d_inode)-> - k_objectid), xadir->d_name.len, - xadir->d_name.name, namelen, name, - IS_PRIVATE(xadir->d_inode) ? "" : - "not "); - dput(dentry); - return -EIO; - } - - err = dir->i_op->unlink(dir, dentry); - if (!err) - d_delete(dentry); - - out_file: - dput(dentry); - - out: - return err; -} - -int reiserfs_xattr_del(struct inode *inode, const char *name) -{ - struct dentry *dir; - int err; - - dir = open_xa_dir(inode, FL_READONLY); - if (IS_ERR(dir)) { - err = PTR_ERR(dir); - goto out; - } - - err = __reiserfs_xattr_del(dir, name, strlen(name)); - dput(dir); - - if (!err) { - inode->i_ctime = CURRENT_TIME_SEC; - mark_inode_dirty(inode); - } - - out: - return err; -} - -/* The following are side effects of other operations that aren't explicitly - * modifying extended attributes. This includes operations such as permissions - * or ownership changes, object deletions, etc. */ - -static int -reiserfs_delete_xattrs_filler(void *buf, const char *name, int namelen, - loff_t offset, u64 ino, unsigned int d_type) -{ - struct dentry *xadir = (struct dentry *)buf; - - return __reiserfs_xattr_del(xadir, name, namelen); - -} - -/* This is called w/ inode->i_mutex downed */ -int reiserfs_delete_xattrs(struct inode *inode) -{ - struct dentry *dir, *root; - int err = 0; - - /* Skip out, an xattr has no xattrs associated with it */ - if (IS_PRIVATE(inode) || get_inode_sd_version(inode) == STAT_DATA_V1 || - !reiserfs_xattrs(inode->i_sb)) { - return 0; - } - reiserfs_read_lock_xattrs(inode->i_sb); - dir = open_xa_dir(inode, FL_READONLY); - reiserfs_read_unlock_xattrs(inode->i_sb); - if (IS_ERR(dir)) { - err = PTR_ERR(dir); - goto out; - } else if (!dir->d_inode) { - dput(dir); - return 0; - } - - lock_kernel(); - err = xattr_readdir(dir->d_inode, reiserfs_delete_xattrs_filler, dir); - if (err) { - unlock_kernel(); - goto out_dir; - } - - /* Leftovers besides . and .. -- that's not good. */ - if (dir->d_inode->i_nlink <= 2) { - root = get_xa_root(inode->i_sb, XATTR_REPLACE); - reiserfs_write_lock_xattrs(inode->i_sb); - err = vfs_rmdir(root->d_inode, dir); - reiserfs_write_unlock_xattrs(inode->i_sb); - dput(root); - } else { - reiserfs_warning(inode->i_sb, "jdm-20006", - "Couldn't remove all entries in directory"); - } - unlock_kernel(); - - out_dir: - dput(dir); - - out: - if (!err) - REISERFS_I(inode)->i_flags = - REISERFS_I(inode)->i_flags & ~i_has_xattr_dir; - return err; -} + while (file_pos < isize) { + size_t chunk; + char *data; + size_t skip = 0; + if (isize - file_pos > PAGE_CACHE_SIZE) + chunk = PAGE_CACHE_SIZE; + else + chunk = isize - file_pos; -struct reiserfs_chown_buf { - struct inode *inode; - struct dentry *xadir; - struct iattr *attrs; -}; + page = reiserfs_get_page(dentry->d_inode, file_pos); + if (IS_ERR(page)) { + err = PTR_ERR(page); + goto out_dput; + } -/* XXX: If there is a better way to do this, I'd love to hear about it */ -static int -reiserfs_chown_xattrs_filler(void *buf, const char *name, int namelen, - loff_t offset, u64 ino, unsigned int d_type) -{ - struct reiserfs_chown_buf *chown_buf = (struct reiserfs_chown_buf *)buf; - struct dentry *xafile, *xadir = chown_buf->xadir; - struct iattr *attrs = chown_buf->attrs; - int err = 0; + lock_page(page); + data = page_address(page); + if (file_pos == 0) { + struct reiserfs_xattr_header *rxh = + (struct reiserfs_xattr_header *)data; + skip = file_pos = sizeof(struct reiserfs_xattr_header); + chunk -= skip; + /* Magic doesn't match up.. */ + if (rxh->h_magic != cpu_to_le32(REISERFS_XATTR_MAGIC)) { + unlock_page(page); + reiserfs_put_page(page); + reiserfs_warning(inode->i_sb, "jdm-20001", + "Invalid magic for xattr (%s) " + "associated with %k", name, + INODE_PKEY(inode)); + err = -EIO; + goto out_dput; + } + hash = le32_to_cpu(rxh->h_hash); + } + memcpy(buffer + buffer_pos, data + skip, chunk); + unlock_page(page); + reiserfs_put_page(page); + file_pos += chunk; + buffer_pos += chunk; + skip = 0; + } + err = isize - sizeof(struct reiserfs_xattr_header); - xafile = lookup_one_len(name, xadir, namelen); - if (IS_ERR(xafile)) - return PTR_ERR(xafile); - else if (!xafile->d_inode) { - dput(xafile); - return -ENODATA; + if (xattr_hash(buffer, isize - sizeof(struct reiserfs_xattr_header)) != + hash) { + reiserfs_warning(inode->i_sb, "jdm-20002", + "Invalid hash for xattr (%s) associated " + "with %k", name, INODE_PKEY(inode)); + err = -EIO; } - if (!S_ISDIR(xafile->d_inode->i_mode)) - err = notify_change(xafile, attrs); - dput(xafile); +out_dput: + dput(dentry); +out: return err; } -int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs) +int reiserfs_xattr_del(struct inode *inode, const char *name) { struct dentry *dir; - int err = 0; - struct reiserfs_chown_buf buf; - unsigned int ia_valid = attrs->ia_valid; + int err; - /* Skip out, an xattr has no xattrs associated with it */ - if (IS_PRIVATE(inode) || get_inode_sd_version(inode) == STAT_DATA_V1 || - !reiserfs_xattrs(inode->i_sb)) { - return 0; - } - reiserfs_read_lock_xattrs(inode->i_sb); dir = open_xa_dir(inode, FL_READONLY); - reiserfs_read_unlock_xattrs(inode->i_sb); if (IS_ERR(dir)) { - if (PTR_ERR(dir) != -ENODATA) - err = PTR_ERR(dir); - goto out; - } else if (!dir->d_inode) { - dput(dir); + err = PTR_ERR(dir); goto out; } - lock_kernel(); - - attrs->ia_valid &= (ATTR_UID | ATTR_GID | ATTR_CTIME); - buf.xadir = dir; - buf.attrs = attrs; - buf.inode = inode; + err = __reiserfs_xattr_del(dir, name, strlen(name)); + dput(dir); - err = xattr_readdir(dir->d_inode, reiserfs_chown_xattrs_filler, &buf); - if (err) { - unlock_kernel(); - goto out_dir; + if (!err) { + inode->i_ctime = CURRENT_TIME_SEC; + mark_inode_dirty(inode); } - err = notify_change(dir, attrs); - unlock_kernel(); - - out_dir: - dput(dir); - out: - attrs->ia_valid = ia_valid; return err; } @@ -1101,6 +1100,94 @@ void reiserfs_xattr_unregister_handlers(void) write_unlock(&handler_lock); } +static int reiserfs_check_acl(struct inode *inode, int mask) +{ + struct posix_acl *acl; + int error = -EAGAIN; /* do regular unix permission checks by default */ + + reiserfs_read_lock_xattr_i(inode); + reiserfs_read_lock_xattrs(inode->i_sb); + + acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS); + + reiserfs_read_unlock_xattrs(inode->i_sb); + reiserfs_read_unlock_xattr_i(inode); + + if (acl) { + if (!IS_ERR(acl)) { + error = posix_acl_permission(inode, acl, mask); + posix_acl_release(acl); + } else if (PTR_ERR(acl) != -ENODATA) + error = PTR_ERR(acl); + } + + return error; +} + +int reiserfs_permission(struct inode *inode, int mask) +{ + /* + * We don't do permission checks on the internal objects. + * Permissions are determined by the "owning" object. + */ + if (IS_PRIVATE(inode)) + return 0; + /* + * Stat data v1 doesn't support ACLs. + */ + if (get_inode_sd_version(inode) == STAT_DATA_V1) + return generic_permission(inode, mask, NULL); + else + return generic_permission(inode, mask, reiserfs_check_acl); +} + +static int create_privroot(struct dentry *dentry) +{ + int err; + struct inode *inode = dentry->d_parent->d_inode; + mutex_lock_nested(&inode->i_mutex, I_MUTEX_XATTR); + err = inode->i_op->mkdir(inode, dentry, 0700); + mutex_unlock(&inode->i_mutex); + if (err) { + dput(dentry); + dentry = NULL; + } + + if (dentry && dentry->d_inode) + reiserfs_info(dentry->d_sb, "Created %s - reserved for xattr " + "storage.\n", PRIVROOT_NAME); + + return err; +} + +static int xattr_mount_check(struct super_block *s) +{ + /* We need generation numbers to ensure that the oid mapping is correct + * v3.5 filesystems don't have them. */ + if (!old_format_only(s)) { + set_bit(REISERFS_XATTRS, &(REISERFS_SB(s)->s_mount_opt)); + } else if (reiserfs_xattrs_optional(s)) { + /* Old format filesystem, but optional xattrs have been enabled + * at mount time. Error out. */ + reiserfs_warning(s, "jdm-20005", + "xattrs/ACLs not supported on pre v3.6 " + "format filesystem. Failing mount."); + return -EOPNOTSUPP; + } else { + /* Old format filesystem, but no optional xattrs have + * been enabled. This means we silently disable xattrs + * on the filesystem. */ + clear_bit(REISERFS_XATTRS, &(REISERFS_SB(s)->s_mount_opt)); + } + + return 0; +} + +#else +int __init reiserfs_xattr_register_handlers(void) { return 0; } +void reiserfs_xattr_unregister_handlers(void) {} +#endif + /* This will catch lookups from the fs root to .reiserfs_priv */ static int xattr_lookup_poison(struct dentry *dentry, struct qstr *q1, struct qstr *name) @@ -1127,47 +1214,23 @@ int reiserfs_xattr_init(struct super_block *s, int mount_flags) { int err = 0; - /* We need generation numbers to ensure that the oid mapping is correct - * v3.5 filesystems don't have them. */ - if (!old_format_only(s)) { - set_bit(REISERFS_XATTRS, &(REISERFS_SB(s)->s_mount_opt)); - } else if (reiserfs_xattrs_optional(s)) { - /* Old format filesystem, but optional xattrs have been enabled - * at mount time. Error out. */ - reiserfs_warning(s, "jdm-20005", - "xattrs/ACLs not supported on pre v3.6 " - "format filesystem. Failing mount."); - err = -EOPNOTSUPP; +#ifdef CONFIG_REISERFS_FS_XATTR + err = xattr_mount_check(s); + if (err) goto error; - } else { - /* Old format filesystem, but no optional xattrs have been enabled. This - * means we silently disable xattrs on the filesystem. */ - clear_bit(REISERFS_XATTRS, &(REISERFS_SB(s)->s_mount_opt)); - } +#endif /* If we don't have the privroot located yet - go find it */ - if (reiserfs_xattrs(s) && !REISERFS_SB(s)->priv_root) { + if (!REISERFS_SB(s)->priv_root) { struct dentry *dentry; dentry = lookup_one_len(PRIVROOT_NAME, s->s_root, strlen(PRIVROOT_NAME)); if (!IS_ERR(dentry)) { - if (!(mount_flags & MS_RDONLY) && !dentry->d_inode) { - struct inode *inode = dentry->d_parent->d_inode; - mutex_lock_nested(&inode->i_mutex, - I_MUTEX_XATTR); - err = inode->i_op->mkdir(inode, dentry, 0700); - mutex_unlock(&inode->i_mutex); - if (err) { - dput(dentry); - dentry = NULL; - } - - if (dentry && dentry->d_inode) - reiserfs_info(s, "Created %s - " - "reserved for xattr " - "storage.\n", - PRIVROOT_NAME); - } else if (!dentry->d_inode) { +#ifdef CONFIG_REISERFS_FS_XATTR + if (!(mount_flags & MS_RDONLY) && !dentry->d_inode) + err = create_privroot(dentry); +#endif + if (!dentry->d_inode) { dput(dentry); dentry = NULL; } @@ -1178,73 +1241,37 @@ int reiserfs_xattr_init(struct super_block *s, int mount_flags) s->s_root->d_op = &xattr_lookup_poison_ops; dentry->d_inode->i_flags |= S_PRIVATE; REISERFS_SB(s)->priv_root = dentry; - } else if (!(mount_flags & MS_RDONLY)) { /* xattrs are unavailable */ - /* If we're read-only it just means that the dir hasn't been - * created. Not an error -- just no xattrs on the fs. We'll - * check again if we go read-write */ +#ifdef CONFIG_REISERFS_FS_XATTR + /* xattrs are unavailable */ + } else if (!(mount_flags & MS_RDONLY)) { + /* If we're read-only it just means that the dir + * hasn't been created. Not an error -- just no + * xattrs on the fs. We'll check again if we + * go read-write */ reiserfs_warning(s, "jdm-20006", "xattrs/ACLs enabled and couldn't " "find/create .reiserfs_priv. " "Failing mount."); err = -EOPNOTSUPP; +#endif } } - error: - /* This is only nonzero if there was an error initializing the xattr - * directory or if there is a condition where we don't support them. */ +#ifdef CONFIG_REISERFS_FS_XATTR +error: if (err) { clear_bit(REISERFS_XATTRS, &(REISERFS_SB(s)->s_mount_opt)); clear_bit(REISERFS_XATTRS_USER, &(REISERFS_SB(s)->s_mount_opt)); clear_bit(REISERFS_POSIXACL, &(REISERFS_SB(s)->s_mount_opt)); } +#endif /* The super_block MS_POSIXACL must mirror the (no)acl mount option. */ s->s_flags = s->s_flags & ~MS_POSIXACL; +#ifdef CONFIG_REISERFS_FS_POSIX_ACL if (reiserfs_posixacl(s)) s->s_flags |= MS_POSIXACL; +#endif return err; } - -static int reiserfs_check_acl(struct inode *inode, int mask) -{ - struct posix_acl *acl; - int error = -EAGAIN; /* do regular unix permission checks by default */ - - reiserfs_read_lock_xattr_i(inode); - reiserfs_read_lock_xattrs(inode->i_sb); - - acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS); - - reiserfs_read_unlock_xattrs(inode->i_sb); - reiserfs_read_unlock_xattr_i(inode); - - if (acl) { - if (!IS_ERR(acl)) { - error = posix_acl_permission(inode, acl, mask); - posix_acl_release(acl); - } else if (PTR_ERR(acl) != -ENODATA) - error = PTR_ERR(acl); - } - - return error; -} - -int reiserfs_permission(struct inode *inode, int mask) -{ - /* - * We don't do permission checks on the internal objects. - * Permissions are determined by the "owning" object. - */ - if (IS_PRIVATE(inode)) - return 0; - - /* - * Stat data v1 doesn't support ACLs. - */ - if (get_inode_sd_version(inode) == STAT_DATA_V1) - return generic_permission(inode, mask, NULL); - else - return generic_permission(inode, mask, reiserfs_check_acl); -} diff --git a/include/linux/reiserfs_fs_sb.h b/include/linux/reiserfs_fs_sb.h index 12fc2a0d13be..cbb8868e844e 100644 --- a/include/linux/reiserfs_fs_sb.h +++ b/include/linux/reiserfs_fs_sb.h @@ -402,8 +402,8 @@ struct reiserfs_sb_info { int reserved_blocks; /* amount of blocks reserved for further allocations */ spinlock_t bitmap_lock; /* this lock on now only used to protect reserved_blocks variable */ struct dentry *priv_root; /* root of /.reiserfs_priv */ -#ifdef CONFIG_REISERFS_FS_XATTR struct dentry *xattr_root; /* root of /.reiserfs_priv/.xa */ +#ifdef CONFIG_REISERFS_FS_XATTR struct rw_semaphore xattr_dir_sem; #endif int j_errno; diff --git a/include/linux/reiserfs_xattr.h b/include/linux/reiserfs_xattr.h index 58f32ba7f5a0..13cdd5e1cb60 100644 --- a/include/linux/reiserfs_xattr.h +++ b/include/linux/reiserfs_xattr.h @@ -43,6 +43,12 @@ struct reiserfs_xattr_handler { struct list_head handlers; }; +int reiserfs_xattr_register_handlers(void) __init; +void reiserfs_xattr_unregister_handlers(void); +int reiserfs_xattr_init(struct super_block *sb, int mount_flags); +int reiserfs_delete_xattrs(struct inode *inode); +int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs); + #ifdef CONFIG_REISERFS_FS_XATTR #define has_xattr_dir(inode) (REISERFS_I(inode)->i_flags & i_has_xattr_dir) ssize_t reiserfs_getxattr(struct dentry *dentry, const char *name, @@ -51,9 +57,6 @@ int reiserfs_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags); ssize_t reiserfs_listxattr(struct dentry *dentry, char *buffer, size_t size); int reiserfs_removexattr(struct dentry *dentry, const char *name); -int reiserfs_delete_xattrs(struct inode *inode); -int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs); -int reiserfs_xattr_init(struct super_block *sb, int mount_flags); int reiserfs_permission(struct inode *inode, int mask); int reiserfs_xattr_del(struct inode *, const char *); @@ -64,9 +67,6 @@ extern struct reiserfs_xattr_handler user_handler; extern struct reiserfs_xattr_handler trusted_handler; extern struct reiserfs_xattr_handler security_handler; -int reiserfs_xattr_register_handlers(void) __init; -void reiserfs_xattr_unregister_handlers(void); - static inline void reiserfs_write_lock_xattrs(struct super_block *sb) { down_write(&REISERFS_XATTR_DIR_SEM(sb)); @@ -121,23 +121,6 @@ static inline void reiserfs_init_xattr_rwsem(struct inode *inode) #define reiserfs_permission NULL -#define reiserfs_xattr_register_handlers() 0 -#define reiserfs_xattr_unregister_handlers() - -static inline int reiserfs_delete_xattrs(struct inode *inode) -{ - return 0; -}; -static inline int reiserfs_chown_xattrs(struct inode *inode, - struct iattr *attrs) -{ - return 0; -}; -static inline int reiserfs_xattr_init(struct super_block *sb, int mount_flags) -{ - sb->s_flags = (sb->s_flags & ~MS_POSIXACL); /* to be sure */ - return 0; -}; static inline void reiserfs_init_xattr_rwsem(struct inode *inode) { } -- cgit v1.2.3 From 6c17675e1e02ebde220ef639a3fb1333928ec2f4 Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Mon, 30 Mar 2009 14:02:34 -0400 Subject: reiserfs: simplify xattr internal file lookups/opens The xattr file open/lookup code is needlessly complex. We can use vfs-level operations to perform the same work, and also simplify the locking constraints. The locking advantages will be exploited in future patches. Signed-off-by: Jeff Mahoney Signed-off-by: Linus Torvalds --- fs/reiserfs/xattr.c | 262 +++++++++++++++++++++++++++------------------------- 1 file changed, 135 insertions(+), 127 deletions(-) (limited to 'fs/reiserfs/xattr.c') diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index f9bcdd5750f7..57920a4df7a4 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c @@ -44,100 +44,123 @@ #include #include #include +#include -#define FL_READONLY 128 -#define FL_DIR_SEM_HELD 256 #define PRIVROOT_NAME ".reiserfs_priv" #define XAROOT_NAME "xattrs" -/* Returns the dentry referring to the root of the extended attribute - * directory tree. If it has already been retrieved, it is used. If it - * hasn't been created and the flags indicate creation is allowed, we - * attempt to create it. On error, we return a pointer-encoded error. - */ -static struct dentry *get_xa_root(struct super_block *sb, int flags) +/* Helpers for inode ops. We do this so that we don't have all the VFS + * overhead and also for proper i_mutex annotation. + * dir->i_mutex must be held for all of them. */ +static int xattr_create(struct inode *dir, struct dentry *dentry, int mode) { - struct dentry *privroot = dget(REISERFS_SB(sb)->priv_root); - struct dentry *xaroot; + BUG_ON(!mutex_is_locked(&dir->i_mutex)); + DQUOT_INIT(dir); + return dir->i_op->create(dir, dentry, mode, NULL); +} - /* This needs to be created at mount-time */ - if (!privroot) - return ERR_PTR(-ENODATA); +static int xattr_mkdir(struct inode *dir, struct dentry *dentry, int mode) +{ + BUG_ON(!mutex_is_locked(&dir->i_mutex)); + DQUOT_INIT(dir); + return dir->i_op->mkdir(dir, dentry, mode); +} - mutex_lock_nested(&privroot->d_inode->i_mutex, I_MUTEX_XATTR); - if (REISERFS_SB(sb)->xattr_root) { - xaroot = dget(REISERFS_SB(sb)->xattr_root); - goto out; - } +/* We use I_MUTEX_CHILD here to silence lockdep. It's safe because xattr + * mutation ops aren't called during rename or splace, which are the + * only other users of I_MUTEX_CHILD. It violates the ordering, but that's + * better than allocating another subclass just for this code. */ +static int xattr_unlink(struct inode *dir, struct dentry *dentry) +{ + int error; + BUG_ON(!mutex_is_locked(&dir->i_mutex)); + DQUOT_INIT(dir); - xaroot = lookup_one_len(XAROOT_NAME, privroot, strlen(XAROOT_NAME)); - if (IS_ERR(xaroot)) { - goto out; - } else if (!xaroot->d_inode) { + mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_CHILD); + error = dir->i_op->unlink(dir, dentry); + mutex_unlock(&dentry->d_inode->i_mutex); + + if (!error) + d_delete(dentry); + return error; +} + +static int xattr_rmdir(struct inode *dir, struct dentry *dentry) +{ + int error; + BUG_ON(!mutex_is_locked(&dir->i_mutex)); + DQUOT_INIT(dir); + + mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_CHILD); + dentry_unhash(dentry); + error = dir->i_op->rmdir(dir, dentry); + if (!error) + dentry->d_inode->i_flags |= S_DEAD; + mutex_unlock(&dentry->d_inode->i_mutex); + if (!error) + d_delete(dentry); + dput(dentry); + + return error; +} + + +#define xattr_may_create(flags) (!flags || flags & XATTR_CREATE) + +/* Returns and possibly creates the xattr dir. */ +static struct dentry *lookup_or_create_dir(struct dentry *parent, + const char *name, int flags) +{ + struct dentry *dentry; + BUG_ON(!parent); + + dentry = lookup_one_len(name, parent, strlen(name)); + if (IS_ERR(dentry)) + return dentry; + else if (!dentry->d_inode) { int err = -ENODATA; - if (flags == 0 || flags & XATTR_CREATE) - err = privroot->d_inode->i_op->mkdir(privroot->d_inode, - xaroot, 0700); + + if (xattr_may_create(flags)) { + mutex_lock_nested(&parent->d_inode->i_mutex, + I_MUTEX_XATTR); + err = xattr_mkdir(parent->d_inode, dentry, 0700); + mutex_unlock(&parent->d_inode->i_mutex); + } + if (err) { - dput(xaroot); - xaroot = ERR_PTR(err); - goto out; + dput(dentry); + dentry = ERR_PTR(err); } } - REISERFS_SB(sb)->xattr_root = dget(xaroot); - out: - mutex_unlock(&privroot->d_inode->i_mutex); - dput(privroot); - return xaroot; + return dentry; +} + +static struct dentry *open_xa_root(struct super_block *sb, int flags) +{ + struct dentry *privroot = REISERFS_SB(sb)->priv_root; + if (!privroot) + return ERR_PTR(-ENODATA); + return lookup_or_create_dir(privroot, XAROOT_NAME, flags); } -/* Opens the directory corresponding to the inode's extended attribute store. - * If flags allow, the tree to the directory may be created. If creation is - * prohibited, -ENODATA is returned. */ static struct dentry *open_xa_dir(const struct inode *inode, int flags) { struct dentry *xaroot, *xadir; char namebuf[17]; - xaroot = get_xa_root(inode->i_sb, flags); + xaroot = open_xa_root(inode->i_sb, flags); if (IS_ERR(xaroot)) return xaroot; - /* ok, we have xaroot open */ snprintf(namebuf, sizeof(namebuf), "%X.%X", le32_to_cpu(INODE_PKEY(inode)->k_objectid), inode->i_generation); - xadir = lookup_one_len(namebuf, xaroot, strlen(namebuf)); - if (IS_ERR(xadir)) { - dput(xaroot); - return xadir; - } - - if (!xadir->d_inode) { - int err; - if (flags == 0 || flags & XATTR_CREATE) { - /* Although there is nothing else trying to create this directory, - * another directory with the same hash may be created, so we need - * to protect against that */ - err = - xaroot->d_inode->i_op->mkdir(xaroot->d_inode, xadir, - 0700); - if (err) { - dput(xaroot); - dput(xadir); - return ERR_PTR(err); - } - } - if (!xadir->d_inode) { - dput(xaroot); - dput(xadir); - return ERR_PTR(-ENODATA); - } - } + xadir = lookup_or_create_dir(xaroot, namebuf, flags); dput(xaroot); return xadir; + } /* @@ -302,13 +325,11 @@ static int xattr_readdir(struct inode *inode, filldir_t filler, void *buf) { int res = -ENOENT; - mutex_lock_nested(&inode->i_mutex, I_MUTEX_XATTR); if (!IS_DEADDIR(inode)) { lock_kernel(); res = __xattr_readdir(inode, buf, filler); unlock_kernel(); } - mutex_unlock(&inode->i_mutex); return res; } @@ -345,9 +366,7 @@ __reiserfs_xattr_del(struct dentry *xadir, const char *name, int namelen) return -EIO; } - err = dir->i_op->unlink(dir, dentry); - if (!err) - d_delete(dentry); + err = xattr_unlink(dir, dentry); out_file: dput(dentry); @@ -381,7 +400,7 @@ int reiserfs_delete_xattrs(struct inode *inode) return 0; reiserfs_read_lock_xattrs(inode->i_sb); - dir = open_xa_dir(inode, FL_READONLY); + dir = open_xa_dir(inode, XATTR_REPLACE); reiserfs_read_unlock_xattrs(inode->i_sb); if (IS_ERR(dir)) { err = PTR_ERR(dir); @@ -391,25 +410,25 @@ int reiserfs_delete_xattrs(struct inode *inode) return 0; } - lock_kernel(); + mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_XATTR); err = xattr_readdir(dir->d_inode, reiserfs_delete_xattrs_filler, dir); - if (err) { - unlock_kernel(); + mutex_unlock(&dir->d_inode->i_mutex); + if (err) goto out_dir; - } /* Leftovers besides . and .. -- that's not good. */ if (dir->d_inode->i_nlink <= 2) { - root = get_xa_root(inode->i_sb, XATTR_REPLACE); + root = open_xa_root(inode->i_sb, XATTR_REPLACE); reiserfs_write_lock_xattrs(inode->i_sb); - err = vfs_rmdir(root->d_inode, dir); + mutex_lock_nested(&root->d_inode->i_mutex, I_MUTEX_XATTR); + err = xattr_rmdir(root->d_inode, dir); + mutex_unlock(&root->d_inode->i_mutex); reiserfs_write_unlock_xattrs(inode->i_sb); dput(root); } else { reiserfs_warning(inode->i_sb, "jdm-20006", "Couldn't remove all entries in directory"); } - unlock_kernel(); out_dir: dput(dir); @@ -445,8 +464,11 @@ reiserfs_chown_xattrs_filler(void *buf, const char *name, int namelen, return -ENODATA; } - if (!S_ISDIR(xafile->d_inode->i_mode)) + if (!S_ISDIR(xafile->d_inode->i_mode)) { + mutex_lock_nested(&xafile->d_inode->i_mutex, I_MUTEX_CHILD); err = notify_change(xafile, attrs); + mutex_unlock(&xafile->d_inode->i_mutex); + } dput(xafile); return err; @@ -464,38 +486,31 @@ int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs) return 0; reiserfs_read_lock_xattrs(inode->i_sb); - dir = open_xa_dir(inode, FL_READONLY); + dir = open_xa_dir(inode, XATTR_REPLACE); reiserfs_read_unlock_xattrs(inode->i_sb); if (IS_ERR(dir)) { if (PTR_ERR(dir) != -ENODATA) err = PTR_ERR(dir); goto out; - } else if (!dir->d_inode) { - dput(dir); - goto out; - } - - lock_kernel(); + } else if (!dir->d_inode) + goto out_dir; attrs->ia_valid &= (ATTR_UID | ATTR_GID | ATTR_CTIME); buf.xadir = dir; buf.attrs = attrs; buf.inode = inode; + mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_XATTR); err = xattr_readdir(dir->d_inode, reiserfs_chown_xattrs_filler, &buf); - if (err) { - unlock_kernel(); - goto out_dir; - } - err = notify_change(dir, attrs); - unlock_kernel(); + if (!err) + err = notify_change(dir, attrs); + mutex_unlock(&dir->d_inode->i_mutex); + attrs->ia_valid = ia_valid; out_dir: dput(dir); - out: - attrs->ia_valid = ia_valid; return err; } @@ -513,47 +528,35 @@ static struct dentry *get_xa_file_dentry(const struct inode *inode, int err = 0; xadir = open_xa_dir(inode, flags); - if (IS_ERR(xadir)) { + if (IS_ERR(xadir)) return ERR_CAST(xadir); - } else if (xadir && !xadir->d_inode) { - dput(xadir); - return ERR_PTR(-ENODATA); - } xafile = lookup_one_len(name, xadir, strlen(name)); if (IS_ERR(xafile)) { - dput(xadir); - return ERR_CAST(xafile); + err = PTR_ERR(xafile); + goto out; } - if (xafile->d_inode) { /* file exists */ - if (flags & XATTR_CREATE) { - err = -EEXIST; - dput(xafile); - goto out; - } - } else if (flags & XATTR_REPLACE || flags & FL_READONLY) { - goto out; - } else { - /* inode->i_mutex is down, so nothing else can try to create - * the same xattr */ - err = xadir->d_inode->i_op->create(xadir->d_inode, xafile, - 0700 | S_IFREG, NULL); + if (xafile->d_inode && (flags & XATTR_CREATE)) + err = -EEXIST; - if (err) { - dput(xafile); - goto out; + if (!xafile->d_inode) { + err = -ENODATA; + if (xattr_may_create(flags)) { + mutex_lock_nested(&xadir->d_inode->i_mutex, + I_MUTEX_XATTR); + err = xattr_create(xadir->d_inode, xafile, + 0700|S_IFREG); + mutex_unlock(&xadir->d_inode->i_mutex); } } + if (err) + dput(xafile); out: dput(xadir); if (err) - xafile = ERR_PTR(err); - else if (!xafile->d_inode) { - dput(xafile); - xafile = ERR_PTR(-ENODATA); - } + return ERR_PTR(err); return xafile; } @@ -633,6 +636,7 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_XATTR); err = notify_change(dentry, &newattrs); + mutex_unlock(&dentry->d_inode->i_mutex); if (err) goto out_filp; @@ -692,7 +696,6 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, } out_filp: - mutex_unlock(&dentry->d_inode->i_mutex); dput(dentry); out: @@ -722,7 +725,7 @@ reiserfs_xattr_get(const struct inode *inode, const char *name, void *buffer, if (get_inode_sd_version(inode) == STAT_DATA_V1) return -EOPNOTSUPP; - dentry = get_xa_file_dentry(inode, name, FL_READONLY); + dentry = get_xa_file_dentry(inode, name, XATTR_REPLACE); if (IS_ERR(dentry)) { err = PTR_ERR(dentry); goto out; @@ -806,13 +809,15 @@ int reiserfs_xattr_del(struct inode *inode, const char *name) struct dentry *dir; int err; - dir = open_xa_dir(inode, FL_READONLY); + dir = open_xa_dir(inode, XATTR_REPLACE); if (IS_ERR(dir)) { err = PTR_ERR(dir); goto out; } + mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_XATTR); err = __reiserfs_xattr_del(dir, name, strlen(name)); + mutex_unlock(&dir->d_inode->i_mutex); dput(dir); if (!err) { @@ -826,6 +831,7 @@ int reiserfs_xattr_del(struct inode *inode, const char *name) /* Actual operations that are exported to VFS-land */ +static struct reiserfs_xattr_handler *find_xattr_handler_prefix(const char *); /* * Inode operation getxattr() * Preliminary locking: we down dentry->d_inode->i_mutex @@ -978,7 +984,7 @@ ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size) reiserfs_read_lock_xattr_i(dentry->d_inode); reiserfs_read_lock_xattrs(dentry->d_sb); - dir = open_xa_dir(dentry->d_inode, FL_READONLY); + dir = open_xa_dir(dentry->d_inode, XATTR_REPLACE); reiserfs_read_unlock_xattrs(dentry->d_sb); if (IS_ERR(dir)) { err = PTR_ERR(dir); @@ -994,7 +1000,9 @@ ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size) REISERFS_I(dentry->d_inode)->i_flags |= i_has_xattr_dir; + mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_XATTR); err = xattr_readdir(dir->d_inode, reiserfs_listxattr_filler, &buf); + mutex_unlock(&dir->d_inode->i_mutex); if (err) goto out_dir; @@ -1146,7 +1154,7 @@ static int create_privroot(struct dentry *dentry) int err; struct inode *inode = dentry->d_parent->d_inode; mutex_lock_nested(&inode->i_mutex, I_MUTEX_XATTR); - err = inode->i_op->mkdir(inode, dentry, 0700); + err = xattr_mkdir(inode, dentry, 0700); mutex_unlock(&inode->i_mutex); if (err) { dput(dentry); -- cgit v1.2.3 From d984561b326cd0fe0d1183d11b9b4fa1d011d21d Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Mon, 30 Mar 2009 14:02:35 -0400 Subject: reiserfs: eliminate per-super xattr lock With the switch to using inode->i_mutex locking during lookups/creation in the xattr root, the per-super xattr lock is no longer needed. This patch removes it. Signed-off-by: Jeff Mahoney Signed-off-by: Linus Torvalds --- fs/reiserfs/inode.c | 14 +------- fs/reiserfs/namei.c | 29 ----------------- fs/reiserfs/super.c | 4 --- fs/reiserfs/xattr.c | 70 +++++++++++++++++++-------------------- fs/reiserfs/xattr_acl.c | 74 +++++++++++++++++++----------------------- include/linux/reiserfs_fs.h | 3 -- include/linux/reiserfs_fs_sb.h | 3 -- include/linux/reiserfs_xattr.h | 28 +++------------- 8 files changed, 74 insertions(+), 151 deletions(-) (limited to 'fs/reiserfs/xattr.c') diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index cd42a8658086..50a73e7afdc8 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c @@ -1957,19 +1957,7 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, inode->i_nlink = 0; th->t_trans_id = 0; /* so the caller can't use this handle later */ unlock_new_inode(inode); /* OK to do even if we hadn't locked it */ - - /* If we were inheriting an ACL, we need to release the lock so that - * iput doesn't deadlock in reiserfs_delete_xattrs. The locking - * code really needs to be reworked, but this will take care of it - * for now. -jeffm */ -#ifdef CONFIG_REISERFS_FS_POSIX_ACL - if (REISERFS_I(dir)->i_acl_default && !IS_ERR(REISERFS_I(dir)->i_acl_default)) { - reiserfs_write_unlock_xattrs(dir->i_sb); - iput(inode); - reiserfs_write_lock_xattrs(dir->i_sb); - } else -#endif - iput(inode); + iput(inode); return err; } diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index c8430f1c824f..ddf1bcd41c87 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c @@ -609,9 +609,6 @@ static int reiserfs_create(struct inode *dir, struct dentry *dentry, int mode, reiserfs_write_lock(dir->i_sb); - if (locked) - reiserfs_write_lock_xattrs(dir->i_sb); - retval = journal_begin(&th, dir->i_sb, jbegin_count); if (retval) { drop_new_inode(inode); @@ -624,11 +621,6 @@ static int reiserfs_create(struct inode *dir, struct dentry *dentry, int mode, if (retval) goto out_failed; - if (locked) { - reiserfs_write_unlock_xattrs(dir->i_sb); - locked = 0; - } - inode->i_op = &reiserfs_file_inode_operations; inode->i_fop = &reiserfs_file_operations; inode->i_mapping->a_ops = &reiserfs_address_space_operations; @@ -655,8 +647,6 @@ static int reiserfs_create(struct inode *dir, struct dentry *dentry, int mode, retval = journal_end(&th, dir->i_sb, jbegin_count); out_failed: - if (locked) - reiserfs_write_unlock_xattrs(dir->i_sb); reiserfs_write_unlock(dir->i_sb); return retval; } @@ -686,9 +676,6 @@ static int reiserfs_mknod(struct inode *dir, struct dentry *dentry, int mode, reiserfs_write_lock(dir->i_sb); - if (locked) - reiserfs_write_lock_xattrs(dir->i_sb); - retval = journal_begin(&th, dir->i_sb, jbegin_count); if (retval) { drop_new_inode(inode); @@ -702,11 +689,6 @@ static int reiserfs_mknod(struct inode *dir, struct dentry *dentry, int mode, goto out_failed; } - if (locked) { - reiserfs_write_unlock_xattrs(dir->i_sb); - locked = 0; - } - inode->i_op = &reiserfs_special_inode_operations; init_special_inode(inode, inode->i_mode, rdev); @@ -736,8 +718,6 @@ static int reiserfs_mknod(struct inode *dir, struct dentry *dentry, int mode, retval = journal_end(&th, dir->i_sb, jbegin_count); out_failed: - if (locked) - reiserfs_write_unlock_xattrs(dir->i_sb); reiserfs_write_unlock(dir->i_sb); return retval; } @@ -767,8 +747,6 @@ static int reiserfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) locked = reiserfs_cache_default_acl(dir); reiserfs_write_lock(dir->i_sb); - if (locked) - reiserfs_write_lock_xattrs(dir->i_sb); retval = journal_begin(&th, dir->i_sb, jbegin_count); if (retval) { @@ -790,11 +768,6 @@ static int reiserfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) goto out_failed; } - if (locked) { - reiserfs_write_unlock_xattrs(dir->i_sb); - locked = 0; - } - reiserfs_update_inode_transaction(inode); reiserfs_update_inode_transaction(dir); @@ -824,8 +797,6 @@ static int reiserfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) unlock_new_inode(inode); retval = journal_end(&th, dir->i_sb, jbegin_count); out_failed: - if (locked) - reiserfs_write_unlock_xattrs(dir->i_sb); reiserfs_write_unlock(dir->i_sb); return retval; } diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index fc7cb4661ee0..6d10f81b4fc1 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -1646,10 +1646,6 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) REISERFS_SB(s)->s_alloc_options.preallocmin = 0; /* Preallocate by 16 blocks (17-1) at once */ REISERFS_SB(s)->s_alloc_options.preallocsize = 17; -#ifdef CONFIG_REISERFS_FS_XATTR - /* Initialize the rwsem for xattr dir */ - init_rwsem(&REISERFS_SB(s)->xattr_dir_sem); -#endif /* setup default block allocator options */ reiserfs_init_alloc_options(s); diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index 57920a4df7a4..62c98829c545 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c @@ -27,6 +27,12 @@ * these are special cases for filesystem ACLs, they are interpreted by the * kernel, in addition, they are negatively and positively cached and attached * to the inode so that unnecessary lookups are avoided. + * + * Locking works like so: + * The xattr root (/.reiserfs_priv/xattrs) is protected by its i_mutex. + * The xattr dir (/.reiserfs_priv/xattrs/.) is protected by + * inode->xattr_sem. + * The xattrs themselves are likewise protected by the xattr_sem. */ #include @@ -392,16 +398,17 @@ reiserfs_delete_xattrs_filler(void *buf, const char *name, int namelen, /* This is called w/ inode->i_mutex downed */ int reiserfs_delete_xattrs(struct inode *inode) { - struct dentry *dir, *root; int err = 0; + struct dentry *dir, *root; + struct reiserfs_transaction_handle th; + int blocks = JOURNAL_PER_BALANCE_CNT * 2 + 2 + + 4 * REISERFS_QUOTA_TRANS_BLOCKS(inode->i_sb); /* Skip out, an xattr has no xattrs associated with it */ if (IS_PRIVATE(inode) || get_inode_sd_version(inode) == STAT_DATA_V1) return 0; - reiserfs_read_lock_xattrs(inode->i_sb); dir = open_xa_dir(inode, XATTR_REPLACE); - reiserfs_read_unlock_xattrs(inode->i_sb); if (IS_ERR(dir)) { err = PTR_ERR(dir); goto out; @@ -416,18 +423,26 @@ int reiserfs_delete_xattrs(struct inode *inode) if (err) goto out_dir; - /* Leftovers besides . and .. -- that's not good. */ - if (dir->d_inode->i_nlink <= 2) { - root = open_xa_root(inode->i_sb, XATTR_REPLACE); - reiserfs_write_lock_xattrs(inode->i_sb); + /* We start a transaction here to avoid a ABBA situation + * between the xattr root's i_mutex and the journal lock. + * Inode creation will inherit an ACL, which requires a + * lookup. The lookup locks the xattr root i_mutex with a + * transaction open. Inode deletion takes teh xattr root + * i_mutex to delete the directory and then starts a + * transaction inside it. Boom. This doesn't incur much + * additional overhead since the reiserfs_rmdir transaction + * will just nest inside the outer transaction. */ + err = journal_begin(&th, inode->i_sb, blocks); + if (!err) { + int jerror; + root = dget(dir->d_parent); mutex_lock_nested(&root->d_inode->i_mutex, I_MUTEX_XATTR); err = xattr_rmdir(root->d_inode, dir); + jerror = journal_end(&th, inode->i_sb, blocks); mutex_unlock(&root->d_inode->i_mutex); - reiserfs_write_unlock_xattrs(inode->i_sb); dput(root); - } else { - reiserfs_warning(inode->i_sb, "jdm-20006", - "Couldn't remove all entries in directory"); + + err = jerror ?: err; } out_dir: @@ -437,6 +452,9 @@ out: if (!err) REISERFS_I(inode)->i_flags = REISERFS_I(inode)->i_flags & ~i_has_xattr_dir; + else + reiserfs_warning(inode->i_sb, "jdm-20004", + "Couldn't remove all xattrs (%d)\n", err); return err; } @@ -485,9 +503,7 @@ int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs) if (IS_PRIVATE(inode) || get_inode_sd_version(inode) == STAT_DATA_V1) return 0; - reiserfs_read_lock_xattrs(inode->i_sb); dir = open_xa_dir(inode, XATTR_REPLACE); - reiserfs_read_unlock_xattrs(inode->i_sb); if (IS_ERR(dir)) { if (PTR_ERR(dir) != -ENODATA) err = PTR_ERR(dir); @@ -731,6 +747,11 @@ reiserfs_xattr_get(const struct inode *inode, const char *name, void *buffer, goto out; } + /* protect against concurrent access. xattrs are backed by + * regular files, but they're not regular files. The updates + * must be atomic from the perspective of the user. */ + mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_XATTR); + isize = i_size_read(dentry->d_inode); REISERFS_I(inode)->i_flags |= i_has_xattr_dir; @@ -798,6 +819,7 @@ reiserfs_xattr_get(const struct inode *inode, const char *name, void *buffer, } out_dput: + mutex_unlock(&dentry->d_inode->i_mutex); dput(dentry); out: @@ -834,7 +856,6 @@ int reiserfs_xattr_del(struct inode *inode, const char *name) static struct reiserfs_xattr_handler *find_xattr_handler_prefix(const char *); /* * Inode operation getxattr() - * Preliminary locking: we down dentry->d_inode->i_mutex */ ssize_t reiserfs_getxattr(struct dentry * dentry, const char *name, void *buffer, @@ -848,9 +869,7 @@ reiserfs_getxattr(struct dentry * dentry, const char *name, void *buffer, return -EOPNOTSUPP; reiserfs_read_lock_xattr_i(dentry->d_inode); - reiserfs_read_lock_xattrs(dentry->d_sb); err = xah->get(dentry->d_inode, name, buffer, size); - reiserfs_read_unlock_xattrs(dentry->d_sb); reiserfs_read_unlock_xattr_i(dentry->d_inode); return err; } @@ -866,23 +885,13 @@ reiserfs_setxattr(struct dentry *dentry, const char *name, const void *value, { struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix(name); int err; - int lock; if (!xah || !reiserfs_xattrs(dentry->d_sb) || get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1) return -EOPNOTSUPP; reiserfs_write_lock_xattr_i(dentry->d_inode); - lock = !has_xattr_dir(dentry->d_inode); - if (lock) - reiserfs_write_lock_xattrs(dentry->d_sb); - else - reiserfs_read_lock_xattrs(dentry->d_sb); err = xah->set(dentry->d_inode, name, value, size, flags); - if (lock) - reiserfs_write_unlock_xattrs(dentry->d_sb); - else - reiserfs_read_unlock_xattrs(dentry->d_sb); reiserfs_write_unlock_xattr_i(dentry->d_inode); return err; } @@ -902,8 +911,6 @@ int reiserfs_removexattr(struct dentry *dentry, const char *name) return -EOPNOTSUPP; reiserfs_write_lock_xattr_i(dentry->d_inode); - reiserfs_read_lock_xattrs(dentry->d_sb); - /* Deletion pre-operation */ if (xah->del) { err = xah->del(dentry->d_inode, name); @@ -917,7 +924,6 @@ int reiserfs_removexattr(struct dentry *dentry, const char *name) mark_inode_dirty(dentry->d_inode); out: - reiserfs_read_unlock_xattrs(dentry->d_sb); reiserfs_write_unlock_xattr_i(dentry->d_inode); return err; } @@ -966,8 +972,6 @@ reiserfs_listxattr_filler(void *buf, const char *name, int namelen, /* * Inode operation listxattr() - * - * Preliminary locking: we down dentry->d_inode->i_mutex */ ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size) { @@ -983,9 +987,7 @@ ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size) return -EOPNOTSUPP; reiserfs_read_lock_xattr_i(dentry->d_inode); - reiserfs_read_lock_xattrs(dentry->d_sb); dir = open_xa_dir(dentry->d_inode, XATTR_REPLACE); - reiserfs_read_unlock_xattrs(dentry->d_sb); if (IS_ERR(dir)) { err = PTR_ERR(dir); if (err == -ENODATA) @@ -1114,11 +1116,9 @@ static int reiserfs_check_acl(struct inode *inode, int mask) int error = -EAGAIN; /* do regular unix permission checks by default */ reiserfs_read_lock_xattr_i(inode); - reiserfs_read_lock_xattrs(inode->i_sb); acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS); - reiserfs_read_unlock_xattrs(inode->i_sb); reiserfs_read_unlock_xattr_i(inode); if (acl) { diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c index 9128e4d5ba64..d63b2c5850c3 100644 --- a/fs/reiserfs/xattr_acl.c +++ b/fs/reiserfs/xattr_acl.c @@ -172,6 +172,29 @@ static void *posix_acl_to_disk(const struct posix_acl *acl, size_t * size) return ERR_PTR(-EINVAL); } +static inline void iset_acl(struct inode *inode, struct posix_acl **i_acl, + struct posix_acl *acl) +{ + spin_lock(&inode->i_lock); + if (*i_acl != ERR_PTR(-ENODATA)) + posix_acl_release(*i_acl); + *i_acl = posix_acl_dup(acl); + spin_unlock(&inode->i_lock); +} + +static inline struct posix_acl *iget_acl(struct inode *inode, + struct posix_acl **i_acl) +{ + struct posix_acl *acl = ERR_PTR(-ENODATA); + + spin_lock(&inode->i_lock); + if (*i_acl != ERR_PTR(-ENODATA)) + acl = posix_acl_dup(*i_acl); + spin_unlock(&inode->i_lock); + + return acl; +} + /* * Inode operation get_posix_acl(). * @@ -199,11 +222,11 @@ struct posix_acl *reiserfs_get_acl(struct inode *inode, int type) return ERR_PTR(-EINVAL); } - if (IS_ERR(*p_acl)) { - if (PTR_ERR(*p_acl) == -ENODATA) - return NULL; - } else if (*p_acl != NULL) - return posix_acl_dup(*p_acl); + acl = iget_acl(inode, p_acl); + if (acl && !IS_ERR(acl)) + return acl; + else if (PTR_ERR(acl) == -ENODATA) + return NULL; size = reiserfs_xattr_get(inode, name, NULL, 0); if (size < 0) { @@ -229,7 +252,7 @@ struct posix_acl *reiserfs_get_acl(struct inode *inode, int type) } else { acl = posix_acl_from_disk(value, retval); if (!IS_ERR(acl)) - *p_acl = posix_acl_dup(acl); + iset_acl(inode, p_acl, acl); } kfree(value); @@ -300,16 +323,8 @@ reiserfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) kfree(value); - if (!error) { - /* Release the old one */ - if (!IS_ERR(*p_acl) && *p_acl) - posix_acl_release(*p_acl); - - if (acl == NULL) - *p_acl = ERR_PTR(-ENODATA); - else - *p_acl = posix_acl_dup(acl); - } + if (!error) + iset_acl(inode, p_acl, acl); return error; } @@ -404,9 +419,7 @@ int reiserfs_cache_default_acl(struct inode *inode) if (reiserfs_posixacl(inode->i_sb) && !IS_PRIVATE(inode)) { struct posix_acl *acl; reiserfs_read_lock_xattr_i(inode); - reiserfs_read_lock_xattrs(inode->i_sb); acl = reiserfs_get_acl(inode, ACL_TYPE_DEFAULT); - reiserfs_read_unlock_xattrs(inode->i_sb); reiserfs_read_unlock_xattr_i(inode); ret = (acl && !IS_ERR(acl)); if (ret) @@ -429,9 +442,7 @@ int reiserfs_acl_chmod(struct inode *inode) return 0; } - reiserfs_read_lock_xattrs(inode->i_sb); acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS); - reiserfs_read_unlock_xattrs(inode->i_sb); if (!acl) return 0; if (IS_ERR(acl)) @@ -442,17 +453,8 @@ int reiserfs_acl_chmod(struct inode *inode) return -ENOMEM; error = posix_acl_chmod_masq(clone, inode->i_mode); if (!error) { - int lock = !has_xattr_dir(inode); reiserfs_write_lock_xattr_i(inode); - if (lock) - reiserfs_write_lock_xattrs(inode->i_sb); - else - reiserfs_read_lock_xattrs(inode->i_sb); error = reiserfs_set_acl(inode, ACL_TYPE_ACCESS, clone); - if (lock) - reiserfs_write_unlock_xattrs(inode->i_sb); - else - reiserfs_read_unlock_xattrs(inode->i_sb); reiserfs_write_unlock_xattr_i(inode); } posix_acl_release(clone); @@ -480,14 +482,9 @@ posix_acl_access_set(struct inode *inode, const char *name, static int posix_acl_access_del(struct inode *inode, const char *name) { struct reiserfs_inode_info *reiserfs_i = REISERFS_I(inode); - struct posix_acl **acl = &reiserfs_i->i_acl_access; if (strlen(name) != sizeof(POSIX_ACL_XATTR_ACCESS) - 1) return -EINVAL; - if (!IS_ERR(*acl) && *acl) { - posix_acl_release(*acl); - *acl = ERR_PTR(-ENODATA); - } - + iset_acl(inode, &reiserfs_i->i_acl_access, ERR_PTR(-ENODATA)); return 0; } @@ -533,14 +530,9 @@ posix_acl_default_set(struct inode *inode, const char *name, static int posix_acl_default_del(struct inode *inode, const char *name) { struct reiserfs_inode_info *reiserfs_i = REISERFS_I(inode); - struct posix_acl **acl = &reiserfs_i->i_acl_default; if (strlen(name) != sizeof(POSIX_ACL_XATTR_DEFAULT) - 1) return -EINVAL; - if (!IS_ERR(*acl) && *acl) { - posix_acl_release(*acl); - *acl = ERR_PTR(-ENODATA); - } - + iset_acl(inode, &reiserfs_i->i_acl_default, ERR_PTR(-ENODATA)); return 0; } diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h index 6c4af98b6767..e00d240314c5 100644 --- a/include/linux/reiserfs_fs.h +++ b/include/linux/reiserfs_fs.h @@ -2224,7 +2224,4 @@ int reiserfs_unpack(struct inode *inode, struct file *filp); #define reiserfs_write_lock( sb ) lock_kernel() #define reiserfs_write_unlock( sb ) unlock_kernel() -/* xattr stuff */ -#define REISERFS_XATTR_DIR_SEM(s) (REISERFS_SB(s)->xattr_dir_sem) - #endif /* _LINUX_REISER_FS_H */ diff --git a/include/linux/reiserfs_fs_sb.h b/include/linux/reiserfs_fs_sb.h index cbb8868e844e..c8aee41ccc23 100644 --- a/include/linux/reiserfs_fs_sb.h +++ b/include/linux/reiserfs_fs_sb.h @@ -403,9 +403,6 @@ struct reiserfs_sb_info { spinlock_t bitmap_lock; /* this lock on now only used to protect reserved_blocks variable */ struct dentry *priv_root; /* root of /.reiserfs_priv */ struct dentry *xattr_root; /* root of /.reiserfs_priv/.xa */ -#ifdef CONFIG_REISERFS_FS_XATTR - struct rw_semaphore xattr_dir_sem; -#endif int j_errno; #ifdef CONFIG_QUOTA char *s_qf_names[MAXQUOTAS]; diff --git a/include/linux/reiserfs_xattr.h b/include/linux/reiserfs_xattr.h index 13cdd5e1cb60..65c16fa51246 100644 --- a/include/linux/reiserfs_xattr.h +++ b/include/linux/reiserfs_xattr.h @@ -67,45 +67,27 @@ extern struct reiserfs_xattr_handler user_handler; extern struct reiserfs_xattr_handler trusted_handler; extern struct reiserfs_xattr_handler security_handler; -static inline void reiserfs_write_lock_xattrs(struct super_block *sb) -{ - down_write(&REISERFS_XATTR_DIR_SEM(sb)); -} -static inline void reiserfs_write_unlock_xattrs(struct super_block *sb) -{ - up_write(&REISERFS_XATTR_DIR_SEM(sb)); -} -static inline void reiserfs_read_lock_xattrs(struct super_block *sb) -{ - down_read(&REISERFS_XATTR_DIR_SEM(sb)); -} - -static inline void reiserfs_read_unlock_xattrs(struct super_block *sb) -{ - up_read(&REISERFS_XATTR_DIR_SEM(sb)); -} - static inline void reiserfs_write_lock_xattr_i(struct inode *inode) { - down_write(&REISERFS_I(inode)->xattr_sem); + down_write(&REISERFS_I(inode)->i_xattr_sem); } static inline void reiserfs_write_unlock_xattr_i(struct inode *inode) { - up_write(&REISERFS_I(inode)->xattr_sem); + up_write(&REISERFS_I(inode)->i_xattr_sem); } static inline void reiserfs_read_lock_xattr_i(struct inode *inode) { - down_read(&REISERFS_I(inode)->xattr_sem); + down_read(&REISERFS_I(inode)->i_xattr_sem); } static inline void reiserfs_read_unlock_xattr_i(struct inode *inode) { - up_read(&REISERFS_I(inode)->xattr_sem); + up_read(&REISERFS_I(inode)->i_xattr_sem); } static inline void reiserfs_init_xattr_rwsem(struct inode *inode) { - init_rwsem(&REISERFS_I(inode)->xattr_sem); + init_rwsem(&REISERFS_I(inode)->i_xattr_sem); } #else -- cgit v1.2.3 From 8b6dd72a441a683cef7ace93de0a57ced4367f00 Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Mon, 30 Mar 2009 14:02:36 -0400 Subject: reiserfs: make per-inode xattr locking more fine grained The per-inode locking can be made more fine-grained to surround just the interaction with the filesystem itself. This really only applies to protecting reads during a write, since concurrent writes are barred with inode->i_mutex at the vfs level. Signed-off-by: Jeff Mahoney Signed-off-by: Linus Torvalds --- fs/reiserfs/xattr.c | 114 +++++++++++++++++++---------------------- fs/reiserfs/xattr_acl.c | 7 +-- include/linux/reiserfs_fs_i.h | 2 +- include/linux/reiserfs_xattr.h | 22 -------- 4 files changed, 55 insertions(+), 90 deletions(-) (limited to 'fs/reiserfs/xattr.c') diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index 62c98829c545..ccb8e4d4c032 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c @@ -29,10 +29,8 @@ * to the inode so that unnecessary lookups are avoided. * * Locking works like so: - * The xattr root (/.reiserfs_priv/xattrs) is protected by its i_mutex. - * The xattr dir (/.reiserfs_priv/xattrs/.) is protected by - * inode->xattr_sem. - * The xattrs themselves are likewise protected by the xattr_sem. + * Directory components (xattr root, xattr dir) are protectd by their i_mutex. + * The xattrs themselves are protected by the xattr_sem. */ #include @@ -55,6 +53,8 @@ #define PRIVROOT_NAME ".reiserfs_priv" #define XAROOT_NAME "xattrs" +static struct reiserfs_xattr_handler *find_xattr_handler_prefix(const char *); + /* Helpers for inode ops. We do this so that we don't have all the VFS * overhead and also for proper i_mutex annotation. * dir->i_mutex must be held for all of them. */ @@ -339,12 +339,14 @@ int xattr_readdir(struct inode *inode, filldir_t filler, void *buf) return res; } +/* expects xadir->d_inode->i_mutex to be locked */ static int __reiserfs_xattr_del(struct dentry *xadir, const char *name, int namelen) { struct dentry *dentry; struct inode *dir = xadir->d_inode; int err = 0; + struct reiserfs_xattr_handler *xah; dentry = lookup_one_len(name, xadir, namelen); if (IS_ERR(dentry)) { @@ -372,6 +374,14 @@ __reiserfs_xattr_del(struct dentry *xadir, const char *name, int namelen) return -EIO; } + /* Deletion pre-operation */ + xah = find_xattr_handler_prefix(name); + if (xah && xah->del) { + err = xah->del(dentry->d_inode, name); + if (err) + goto out; + } + err = xattr_unlink(dir, dentry); out_file: @@ -398,7 +408,7 @@ reiserfs_delete_xattrs_filler(void *buf, const char *name, int namelen, /* This is called w/ inode->i_mutex downed */ int reiserfs_delete_xattrs(struct inode *inode) { - int err = 0; + int err = -ENODATA; struct dentry *dir, *root; struct reiserfs_transaction_handle th; int blocks = JOURNAL_PER_BALANCE_CNT * 2 + 2 + @@ -414,14 +424,19 @@ int reiserfs_delete_xattrs(struct inode *inode) goto out; } else if (!dir->d_inode) { dput(dir); - return 0; + goto out; } mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_XATTR); err = xattr_readdir(dir->d_inode, reiserfs_delete_xattrs_filler, dir); mutex_unlock(&dir->d_inode->i_mutex); - if (err) - goto out_dir; + if (err) { + dput(dir); + goto out; + } + + root = dget(dir->d_parent); + dput(dir); /* We start a transaction here to avoid a ABBA situation * between the xattr root's i_mutex and the journal lock. @@ -435,19 +450,14 @@ int reiserfs_delete_xattrs(struct inode *inode) err = journal_begin(&th, inode->i_sb, blocks); if (!err) { int jerror; - root = dget(dir->d_parent); mutex_lock_nested(&root->d_inode->i_mutex, I_MUTEX_XATTR); err = xattr_rmdir(root->d_inode, dir); jerror = journal_end(&th, inode->i_sb, blocks); mutex_unlock(&root->d_inode->i_mutex); - dput(root); - err = jerror ?: err; } -out_dir: - dput(dir); - + dput(root); out: if (!err) REISERFS_I(inode)->i_flags = @@ -484,7 +494,7 @@ reiserfs_chown_xattrs_filler(void *buf, const char *name, int namelen, if (!S_ISDIR(xafile->d_inode->i_mode)) { mutex_lock_nested(&xafile->d_inode->i_mutex, I_MUTEX_CHILD); - err = notify_change(xafile, attrs); + err = reiserfs_setattr(xafile, attrs); mutex_unlock(&xafile->d_inode->i_mutex); } dput(xafile); @@ -520,13 +530,16 @@ int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs) err = xattr_readdir(dir->d_inode, reiserfs_chown_xattrs_filler, &buf); if (!err) - err = notify_change(dir, attrs); + err = reiserfs_setattr(dir, attrs); mutex_unlock(&dir->d_inode->i_mutex); attrs->ia_valid = ia_valid; out_dir: dput(dir); out: + if (err) + reiserfs_warning(inode->i_sb, "jdm-20007", + "Couldn't chown all xattrs (%d)\n", err); return err; } @@ -635,9 +648,8 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, if (get_inode_sd_version(inode) == STAT_DATA_V1) return -EOPNOTSUPP; - /* Empty xattrs are ok, they're just empty files, no hash */ - if (buffer && buffer_size) - xahash = xattr_hash(buffer, buffer_size); + if (!buffer) + return reiserfs_xattr_del(inode, name); dentry = get_xa_file_dentry(inode, name, flags); if (IS_ERR(dentry)) { @@ -645,13 +657,19 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, goto out; } + down_write(&REISERFS_I(inode)->i_xattr_sem); + + xahash = xattr_hash(buffer, buffer_size); REISERFS_I(inode)->i_flags |= i_has_xattr_dir; /* Resize it so we're ok to write there */ newattrs.ia_size = buffer_size; + newattrs.ia_ctime = current_fs_time(inode->i_sb); newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_XATTR); - err = notify_change(dentry, &newattrs); + down_write(&dentry->d_inode->i_alloc_sem); + err = reiserfs_setattr(dentry, &newattrs); + up_write(&dentry->d_inode->i_alloc_sem); mutex_unlock(&dentry->d_inode->i_mutex); if (err) goto out_filp; @@ -712,6 +730,7 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, } out_filp: + up_write(&REISERFS_I(inode)->i_xattr_sem); dput(dentry); out: @@ -747,10 +766,7 @@ reiserfs_xattr_get(const struct inode *inode, const char *name, void *buffer, goto out; } - /* protect against concurrent access. xattrs are backed by - * regular files, but they're not regular files. The updates - * must be atomic from the perspective of the user. */ - mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_XATTR); + down_read(&REISERFS_I(inode)->i_xattr_sem); isize = i_size_read(dentry->d_inode); REISERFS_I(inode)->i_flags |= i_has_xattr_dir; @@ -758,12 +774,12 @@ reiserfs_xattr_get(const struct inode *inode, const char *name, void *buffer, /* Just return the size needed */ if (buffer == NULL) { err = isize - sizeof(struct reiserfs_xattr_header); - goto out_dput; + goto out_unlock; } if (buffer_size < isize - sizeof(struct reiserfs_xattr_header)) { err = -ERANGE; - goto out_dput; + goto out_unlock; } while (file_pos < isize) { @@ -778,7 +794,7 @@ reiserfs_xattr_get(const struct inode *inode, const char *name, void *buffer, page = reiserfs_get_page(dentry->d_inode, file_pos); if (IS_ERR(page)) { err = PTR_ERR(page); - goto out_dput; + goto out_unlock; } lock_page(page); @@ -797,7 +813,7 @@ reiserfs_xattr_get(const struct inode *inode, const char *name, void *buffer, "associated with %k", name, INODE_PKEY(inode)); err = -EIO; - goto out_dput; + goto out_unlock; } hash = le32_to_cpu(rxh->h_hash); } @@ -818,8 +834,8 @@ reiserfs_xattr_get(const struct inode *inode, const char *name, void *buffer, err = -EIO; } -out_dput: - mutex_unlock(&dentry->d_inode->i_mutex); +out_unlock: + up_read(&REISERFS_I(inode)->i_xattr_sem); dput(dentry); out: @@ -852,8 +868,6 @@ int reiserfs_xattr_del(struct inode *inode, const char *name) } /* Actual operations that are exported to VFS-land */ - -static struct reiserfs_xattr_handler *find_xattr_handler_prefix(const char *); /* * Inode operation getxattr() */ @@ -868,9 +882,7 @@ reiserfs_getxattr(struct dentry * dentry, const char *name, void *buffer, get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1) return -EOPNOTSUPP; - reiserfs_read_lock_xattr_i(dentry->d_inode); err = xah->get(dentry->d_inode, name, buffer, size); - reiserfs_read_unlock_xattr_i(dentry->d_inode); return err; } @@ -890,9 +902,7 @@ reiserfs_setxattr(struct dentry *dentry, const char *name, const void *value, get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1) return -EOPNOTSUPP; - reiserfs_write_lock_xattr_i(dentry->d_inode); err = xah->set(dentry->d_inode, name, value, size, flags); - reiserfs_write_unlock_xattr_i(dentry->d_inode); return err; } @@ -910,21 +920,11 @@ int reiserfs_removexattr(struct dentry *dentry, const char *name) get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1) return -EOPNOTSUPP; - reiserfs_write_lock_xattr_i(dentry->d_inode); - /* Deletion pre-operation */ - if (xah->del) { - err = xah->del(dentry->d_inode, name); - if (err) - goto out; - } - err = reiserfs_xattr_del(dentry->d_inode, name); dentry->d_inode->i_ctime = CURRENT_TIME_SEC; mark_inode_dirty(dentry->d_inode); - out: - reiserfs_write_unlock_xattr_i(dentry->d_inode); return err; } @@ -986,7 +986,6 @@ ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size) get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1) return -EOPNOTSUPP; - reiserfs_read_lock_xattr_i(dentry->d_inode); dir = open_xa_dir(dentry->d_inode, XATTR_REPLACE); if (IS_ERR(dir)) { err = PTR_ERR(dir); @@ -1005,19 +1004,16 @@ ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size) mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_XATTR); err = xattr_readdir(dir->d_inode, reiserfs_listxattr_filler, &buf); mutex_unlock(&dir->d_inode->i_mutex); - if (err) - goto out_dir; - if (buf.r_pos > buf.r_size && buffer != NULL) - err = -ERANGE; - else - err = buf.r_pos; + if (!err) { + if (buf.r_pos > buf.r_size && buffer != NULL) + err = -ERANGE; + else + err = buf.r_pos; + } - out_dir: dput(dir); - - out: - reiserfs_read_unlock_xattr_i(dentry->d_inode); +out: return err; } @@ -1115,12 +1111,8 @@ static int reiserfs_check_acl(struct inode *inode, int mask) struct posix_acl *acl; int error = -EAGAIN; /* do regular unix permission checks by default */ - reiserfs_read_lock_xattr_i(inode); - acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS); - reiserfs_read_unlock_xattr_i(inode); - if (acl) { if (!IS_ERR(acl)) { error = posix_acl_permission(inode, acl, mask); diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c index d63b2c5850c3..d3ce6ee9b262 100644 --- a/fs/reiserfs/xattr_acl.c +++ b/fs/reiserfs/xattr_acl.c @@ -418,9 +418,7 @@ int reiserfs_cache_default_acl(struct inode *inode) int ret = 0; if (reiserfs_posixacl(inode->i_sb) && !IS_PRIVATE(inode)) { struct posix_acl *acl; - reiserfs_read_lock_xattr_i(inode); acl = reiserfs_get_acl(inode, ACL_TYPE_DEFAULT); - reiserfs_read_unlock_xattr_i(inode); ret = (acl && !IS_ERR(acl)); if (ret) posix_acl_release(acl); @@ -452,11 +450,8 @@ int reiserfs_acl_chmod(struct inode *inode) if (!clone) return -ENOMEM; error = posix_acl_chmod_masq(clone, inode->i_mode); - if (!error) { - reiserfs_write_lock_xattr_i(inode); + if (!error) error = reiserfs_set_acl(inode, ACL_TYPE_ACCESS, clone); - reiserfs_write_unlock_xattr_i(inode); - } posix_acl_release(clone); return error; } diff --git a/include/linux/reiserfs_fs_i.h b/include/linux/reiserfs_fs_i.h index 201dd910b042..76360b36ac33 100644 --- a/include/linux/reiserfs_fs_i.h +++ b/include/linux/reiserfs_fs_i.h @@ -59,7 +59,7 @@ struct reiserfs_inode_info { struct posix_acl *i_acl_default; #endif #ifdef CONFIG_REISERFS_FS_XATTR - struct rw_semaphore xattr_sem; + struct rw_semaphore i_xattr_sem; #endif struct inode vfs_inode; }; diff --git a/include/linux/reiserfs_xattr.h b/include/linux/reiserfs_xattr.h index 65c16fa51246..3bd154fd56e9 100644 --- a/include/linux/reiserfs_xattr.h +++ b/include/linux/reiserfs_xattr.h @@ -67,24 +67,6 @@ extern struct reiserfs_xattr_handler user_handler; extern struct reiserfs_xattr_handler trusted_handler; extern struct reiserfs_xattr_handler security_handler; -static inline void reiserfs_write_lock_xattr_i(struct inode *inode) -{ - down_write(&REISERFS_I(inode)->i_xattr_sem); -} -static inline void reiserfs_write_unlock_xattr_i(struct inode *inode) -{ - up_write(&REISERFS_I(inode)->i_xattr_sem); -} -static inline void reiserfs_read_lock_xattr_i(struct inode *inode) -{ - down_read(&REISERFS_I(inode)->i_xattr_sem); -} - -static inline void reiserfs_read_unlock_xattr_i(struct inode *inode) -{ - up_read(&REISERFS_I(inode)->i_xattr_sem); -} - static inline void reiserfs_init_xattr_rwsem(struct inode *inode) { init_rwsem(&REISERFS_I(inode)->i_xattr_sem); @@ -96,10 +78,6 @@ static inline void reiserfs_init_xattr_rwsem(struct inode *inode) #define reiserfs_setxattr NULL #define reiserfs_listxattr NULL #define reiserfs_removexattr NULL -#define reiserfs_write_lock_xattrs(sb) do {;} while(0) -#define reiserfs_write_unlock_xattrs(sb) do {;} while(0) -#define reiserfs_read_lock_xattrs(sb) -#define reiserfs_read_unlock_xattrs(sb) #define reiserfs_permission NULL -- cgit v1.2.3 From 8ecbe550a142fe604874afa477ea68986f89b86c Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Mon, 30 Mar 2009 14:02:37 -0400 Subject: reiserfs: remove i_has_xattr_dir With the changes to xattr root locking, the i_has_xattr_dir flag is no longer needed. This patch removes it. Signed-off-by: Jeff Mahoney Signed-off-by: Linus Torvalds --- fs/reiserfs/xattr.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'fs/reiserfs/xattr.c') diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index ccb8e4d4c032..8d7e5d9ae17c 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c @@ -459,10 +459,7 @@ int reiserfs_delete_xattrs(struct inode *inode) dput(root); out: - if (!err) - REISERFS_I(inode)->i_flags = - REISERFS_I(inode)->i_flags & ~i_has_xattr_dir; - else + if (err) reiserfs_warning(inode->i_sb, "jdm-20004", "Couldn't remove all xattrs (%d)\n", err); return err; @@ -660,7 +657,6 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, down_write(&REISERFS_I(inode)->i_xattr_sem); xahash = xattr_hash(buffer, buffer_size); - REISERFS_I(inode)->i_flags |= i_has_xattr_dir; /* Resize it so we're ok to write there */ newattrs.ia_size = buffer_size; @@ -769,7 +765,6 @@ reiserfs_xattr_get(const struct inode *inode, const char *name, void *buffer, down_read(&REISERFS_I(inode)->i_xattr_sem); isize = i_size_read(dentry->d_inode); - REISERFS_I(inode)->i_flags |= i_has_xattr_dir; /* Just return the size needed */ if (buffer == NULL) { @@ -999,8 +994,6 @@ ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size) buf.r_pos = 0; buf.r_inode = dentry->d_inode; - REISERFS_I(dentry->d_inode)->i_flags |= i_has_xattr_dir; - mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_XATTR); err = xattr_readdir(dir->d_inode, reiserfs_listxattr_filler, &buf); mutex_unlock(&dir->d_inode->i_mutex); -- cgit v1.2.3 From 48b32a3553a54740d236b79a90f20147a25875e3 Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Mon, 30 Mar 2009 14:02:38 -0400 Subject: reiserfs: use generic xattr handlers Christoph Hellwig had asked me quite some time ago to port the reiserfs xattrs to the generic xattr interface. This patch replaces the reiserfs-specific xattr handling code with the generic struct xattr_handler. However, since reiserfs doesn't split the prefix and name when accessing xattrs, it can't leverage generic_{set,get,list,remove}xattr without needlessly reconstructing the name on the back end. Update 7/26/07: Added missing dput() to deletion path. Update 8/30/07: Added missing mark_inode_dirty when i_mode is used to represent an ACL and no previous ACL existed. Signed-off-by: Jeff Mahoney Signed-off-by: Linus Torvalds --- fs/reiserfs/super.c | 7 - fs/reiserfs/xattr.c | 467 +++++++++++++++++------------------------ fs/reiserfs/xattr_acl.c | 79 +++---- fs/reiserfs/xattr_security.c | 26 +-- fs/reiserfs/xattr_trusted.c | 45 +--- fs/reiserfs/xattr_user.c | 31 +-- include/linux/reiserfs_acl.h | 16 +- include/linux/reiserfs_fs_sb.h | 3 +- include/linux/reiserfs_xattr.h | 25 +-- 9 files changed, 258 insertions(+), 441 deletions(-) (limited to 'fs/reiserfs/xattr.c') diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 6d10f81b4fc1..4a1e16362ebd 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -2263,9 +2263,6 @@ static int __init init_reiserfs_fs(void) return ret; } - if ((ret = reiserfs_xattr_register_handlers())) - goto failed_reiserfs_xattr_register_handlers; - reiserfs_proc_info_global_init(); reiserfs_proc_register_global("version", reiserfs_global_version_in_proc); @@ -2276,9 +2273,6 @@ static int __init init_reiserfs_fs(void) return 0; } - reiserfs_xattr_unregister_handlers(); - - failed_reiserfs_xattr_register_handlers: reiserfs_proc_unregister_global("version"); reiserfs_proc_info_global_done(); destroy_inodecache(); @@ -2288,7 +2282,6 @@ static int __init init_reiserfs_fs(void) static void __exit exit_reiserfs_fs(void) { - reiserfs_xattr_unregister_handlers(); reiserfs_proc_unregister_global("version"); reiserfs_proc_info_global_done(); unregister_filesystem(&reiserfs_fs_type); diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index 8d7e5d9ae17c..d3ce27436605 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c @@ -53,7 +53,6 @@ #define PRIVROOT_NAME ".reiserfs_priv" #define XAROOT_NAME "xattrs" -static struct reiserfs_xattr_handler *find_xattr_handler_prefix(const char *); /* Helpers for inode ops. We do this so that we don't have all the VFS * overhead and also for proper i_mutex annotation. @@ -110,7 +109,6 @@ static int xattr_rmdir(struct inode *dir, struct dentry *dentry) return error; } - #define xattr_may_create(flags) (!flags || flags & XATTR_CREATE) /* Returns and possibly creates the xattr dir. */ @@ -339,14 +337,17 @@ int xattr_readdir(struct inode *inode, filldir_t filler, void *buf) return res; } -/* expects xadir->d_inode->i_mutex to be locked */ +/* The following are side effects of other operations that aren't explicitly + * modifying extended attributes. This includes operations such as permissions + * or ownership changes, object deletions, etc. */ + static int -__reiserfs_xattr_del(struct dentry *xadir, const char *name, int namelen) +reiserfs_delete_xattrs_filler(void *buf, const char *name, int namelen, + loff_t offset, u64 ino, unsigned int d_type) { + struct dentry *xadir = (struct dentry *)buf; struct dentry *dentry; - struct inode *dir = xadir->d_inode; int err = 0; - struct reiserfs_xattr_handler *xah; dentry = lookup_one_len(name, xadir, namelen); if (IS_ERR(dentry)) { @@ -361,28 +362,7 @@ __reiserfs_xattr_del(struct dentry *xadir, const char *name, int namelen) if (S_ISDIR(dentry->d_inode->i_mode)) goto out_file; - if (!IS_PRIVATE(dentry->d_inode)) { - reiserfs_error(dir->i_sb, "jdm-20003", - "OID %08x [%.*s/%.*s] doesn't have " - "priv flag set [parent is %sset].", - le32_to_cpu(INODE_PKEY(dentry->d_inode)-> - k_objectid), xadir->d_name.len, - xadir->d_name.name, namelen, name, - IS_PRIVATE(xadir->d_inode) ? "" : - "not "); - dput(dentry); - return -EIO; - } - - /* Deletion pre-operation */ - xah = find_xattr_handler_prefix(name); - if (xah && xah->del) { - err = xah->del(dentry->d_inode, name); - if (err) - goto out; - } - - err = xattr_unlink(dir, dentry); + err = xattr_unlink(xadir->d_inode, dentry); out_file: dput(dentry); @@ -391,20 +371,6 @@ out: return err; } -/* The following are side effects of other operations that aren't explicitly - * modifying extended attributes. This includes operations such as permissions - * or ownership changes, object deletions, etc. */ - -static int -reiserfs_delete_xattrs_filler(void *buf, const char *name, int namelen, - loff_t offset, u64 ino, unsigned int d_type) -{ - struct dentry *xadir = (struct dentry *)buf; - - return __reiserfs_xattr_del(xadir, name, namelen); - -} - /* This is called w/ inode->i_mutex downed */ int reiserfs_delete_xattrs(struct inode *inode) { @@ -541,14 +507,11 @@ out: } #ifdef CONFIG_REISERFS_FS_XATTR -static struct reiserfs_xattr_handler *find_xattr_handler_prefix(const char - *prefix); - /* Returns a dentry corresponding to a specific extended attribute file * for the inode. If flags allow, the file is created. Otherwise, a * valid or negative dentry, or an error is returned. */ -static struct dentry *get_xa_file_dentry(const struct inode *inode, - const char *name, int flags) +static struct dentry *xattr_lookup(struct inode *inode, const char *name, + int flags) { struct dentry *xadir, *xafile; int err = 0; @@ -623,6 +586,45 @@ int reiserfs_commit_write(struct file *f, struct page *page, int reiserfs_prepare_write(struct file *f, struct page *page, unsigned from, unsigned to); +static void update_ctime(struct inode *inode) +{ + struct timespec now = current_fs_time(inode->i_sb); + if (hlist_unhashed(&inode->i_hash) || !inode->i_nlink || + timespec_equal(&inode->i_ctime, &now)) + return; + + inode->i_ctime = CURRENT_TIME_SEC; + mark_inode_dirty(inode); +} + +static int lookup_and_delete_xattr(struct inode *inode, const char *name) +{ + int err = 0; + struct dentry *dentry, *xadir; + + xadir = open_xa_dir(inode, XATTR_REPLACE); + if (IS_ERR(xadir)) + return PTR_ERR(xadir); + + dentry = lookup_one_len(name, xadir, strlen(name)); + if (IS_ERR(dentry)) { + err = PTR_ERR(dentry); + goto out_dput; + } + + if (dentry->d_inode) { + mutex_lock_nested(&xadir->d_inode->i_mutex, I_MUTEX_XATTR); + err = xattr_unlink(xadir->d_inode, dentry); + mutex_unlock(&xadir->d_inode->i_mutex); + update_ctime(inode); + } + + dput(dentry); +out_dput: + dput(xadir); + return err; +} + /* Generic extended attribute operations that can be used by xa plugins */ @@ -630,8 +632,8 @@ int reiserfs_prepare_write(struct file *f, struct page *page, * inode->i_mutex: down */ int -reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, - size_t buffer_size, int flags) +__reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, + size_t buffer_size, int flags) { int err = 0; struct dentry *dentry; @@ -639,37 +641,22 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, char *data; size_t file_pos = 0; size_t buffer_pos = 0; - struct iattr newattrs; + size_t new_size; __u32 xahash = 0; if (get_inode_sd_version(inode) == STAT_DATA_V1) return -EOPNOTSUPP; if (!buffer) - return reiserfs_xattr_del(inode, name); + return lookup_and_delete_xattr(inode, name); - dentry = get_xa_file_dentry(inode, name, flags); - if (IS_ERR(dentry)) { - err = PTR_ERR(dentry); - goto out; - } + dentry = xattr_lookup(inode, name, flags); + if (IS_ERR(dentry)) + return PTR_ERR(dentry); down_write(&REISERFS_I(inode)->i_xattr_sem); xahash = xattr_hash(buffer, buffer_size); - - /* Resize it so we're ok to write there */ - newattrs.ia_size = buffer_size; - newattrs.ia_ctime = current_fs_time(inode->i_sb); - newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; - mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_XATTR); - down_write(&dentry->d_inode->i_alloc_sem); - err = reiserfs_setattr(dentry, &newattrs); - up_write(&dentry->d_inode->i_alloc_sem); - mutex_unlock(&dentry->d_inode->i_mutex); - if (err) - goto out_filp; - while (buffer_pos < buffer_size || buffer_pos == 0) { size_t chunk; size_t skip = 0; @@ -682,7 +669,7 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, page = reiserfs_get_page(dentry->d_inode, file_pos); if (IS_ERR(page)) { err = PTR_ERR(page); - goto out_filp; + goto out_unlock; } lock_page(page); @@ -716,20 +703,33 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, break; } - /* We can't mark the inode dirty if it's not hashed. This is the case - * when we're inheriting the default ACL. If we dirty it, the inode - * gets marked dirty, but won't (ever) make it onto the dirty list until - * it's synced explicitly to clear I_DIRTY. This is bad. */ - if (!hlist_unhashed(&inode->i_hash)) { - inode->i_ctime = CURRENT_TIME_SEC; - mark_inode_dirty(inode); - } - - out_filp: + new_size = buffer_size + sizeof(struct reiserfs_xattr_header); + if (!err && new_size < i_size_read(dentry->d_inode)) { + struct iattr newattrs = { + .ia_ctime = current_fs_time(inode->i_sb), + .ia_size = buffer_size, + .ia_valid = ATTR_SIZE | ATTR_CTIME, + }; + mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_XATTR); + down_write(&dentry->d_inode->i_alloc_sem); + err = reiserfs_setattr(dentry, &newattrs); + up_write(&dentry->d_inode->i_alloc_sem); + mutex_unlock(&dentry->d_inode->i_mutex); + } else + update_ctime(inode); +out_unlock: up_write(&REISERFS_I(inode)->i_xattr_sem); dput(dentry); + return err; +} - out: +int +reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, + size_t buffer_size, int flags) +{ + int err = __reiserfs_xattr_set(inode, name, buffer, buffer_size, flags); + if (err == -ENODATA) + err = 0; return err; } @@ -737,7 +737,7 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, * inode->i_mutex: down */ int -reiserfs_xattr_get(const struct inode *inode, const char *name, void *buffer, +reiserfs_xattr_get(struct inode *inode, const char *name, void *buffer, size_t buffer_size) { ssize_t err = 0; @@ -756,7 +756,7 @@ reiserfs_xattr_get(const struct inode *inode, const char *name, void *buffer, if (get_inode_sd_version(inode) == STAT_DATA_V1) return -EOPNOTSUPP; - dentry = get_xa_file_dentry(inode, name, XATTR_REPLACE); + dentry = xattr_lookup(inode, name, XATTR_REPLACE); if (IS_ERR(dentry)) { err = PTR_ERR(dentry); goto out; @@ -837,32 +837,53 @@ out: return err; } -int reiserfs_xattr_del(struct inode *inode, const char *name) -{ - struct dentry *dir; - int err; +/* Actual operations that are exported to VFS-land */ +struct xattr_handler *reiserfs_xattr_handlers[] = { + &reiserfs_xattr_user_handler, + &reiserfs_xattr_trusted_handler, +#ifdef CONFIG_REISERFS_FS_SECURITY + &reiserfs_xattr_security_handler, +#endif +#ifdef CONFIG_REISERFS_FS_POSIX_ACL + &reiserfs_posix_acl_access_handler, + &reiserfs_posix_acl_default_handler, +#endif + NULL +}; - dir = open_xa_dir(inode, XATTR_REPLACE); - if (IS_ERR(dir)) { - err = PTR_ERR(dir); - goto out; - } +/* + * In order to implement different sets of xattr operations for each xattr + * prefix with the generic xattr API, a filesystem should create a + * null-terminated array of struct xattr_handler (one for each prefix) and + * hang a pointer to it off of the s_xattr field of the superblock. + * + * The generic_fooxattr() functions will use this list to dispatch xattr + * operations to the correct xattr_handler. + */ +#define for_each_xattr_handler(handlers, handler) \ + for ((handler) = *(handlers)++; \ + (handler) != NULL; \ + (handler) = *(handlers)++) - mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_XATTR); - err = __reiserfs_xattr_del(dir, name, strlen(name)); - mutex_unlock(&dir->d_inode->i_mutex); - dput(dir); +/* This is the implementation for the xattr plugin infrastructure */ +static inline struct xattr_handler * +find_xattr_handler_prefix(struct xattr_handler **handlers, + const char *name) +{ + struct xattr_handler *xah; - if (!err) { - inode->i_ctime = CURRENT_TIME_SEC; - mark_inode_dirty(inode); + if (!handlers) + return NULL; + + for_each_xattr_handler(handlers, xah) { + if (strncmp(xah->prefix, name, strlen(xah->prefix)) == 0) + break; } - out: - return err; + return xah; } -/* Actual operations that are exported to VFS-land */ + /* * Inode operation getxattr() */ @@ -870,15 +891,15 @@ ssize_t reiserfs_getxattr(struct dentry * dentry, const char *name, void *buffer, size_t size) { - struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix(name); - int err; + struct inode *inode = dentry->d_inode; + struct xattr_handler *handler; - if (!xah || !reiserfs_xattrs(dentry->d_sb) || - get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1) + handler = find_xattr_handler_prefix(inode->i_sb->s_xattr, name); + + if (!handler || get_inode_sd_version(inode) == STAT_DATA_V1) return -EOPNOTSUPP; - err = xah->get(dentry->d_inode, name, buffer, size); - return err; + return handler->get(inode, name, buffer, size); } /* @@ -890,15 +911,15 @@ int reiserfs_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags) { - struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix(name); - int err; + struct inode *inode = dentry->d_inode; + struct xattr_handler *handler; - if (!xah || !reiserfs_xattrs(dentry->d_sb) || - get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1) + handler = find_xattr_handler_prefix(inode->i_sb->s_xattr, name); + + if (!handler || get_inode_sd_version(inode) == STAT_DATA_V1) return -EOPNOTSUPP; - err = xah->set(dentry->d_inode, name, value, size, flags); - return err; + return handler->set(inode, name, value, size, flags); } /* @@ -908,71 +929,65 @@ reiserfs_setxattr(struct dentry *dentry, const char *name, const void *value, */ int reiserfs_removexattr(struct dentry *dentry, const char *name) { - int err; - struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix(name); + struct inode *inode = dentry->d_inode; + struct xattr_handler *handler; + handler = find_xattr_handler_prefix(inode->i_sb->s_xattr, name); - if (!xah || !reiserfs_xattrs(dentry->d_sb) || - get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1) + if (!handler || get_inode_sd_version(inode) == STAT_DATA_V1) return -EOPNOTSUPP; - err = reiserfs_xattr_del(dentry->d_inode, name); - - dentry->d_inode->i_ctime = CURRENT_TIME_SEC; - mark_inode_dirty(dentry->d_inode); - - return err; + return handler->set(inode, name, NULL, 0, XATTR_REPLACE); } -/* This is what filldir will use: - * r_pos will always contain the amount of space required for the entire - * list. If r_pos becomes larger than r_size, we need more space and we - * return an error indicating this. If r_pos is less than r_size, then we've - * filled the buffer successfully and we return success */ -struct reiserfs_listxattr_buf { - int r_pos; - int r_size; - char *r_buf; - struct inode *r_inode; +struct listxattr_buf { + size_t size; + size_t pos; + char *buf; + struct inode *inode; }; -static int -reiserfs_listxattr_filler(void *buf, const char *name, int namelen, - loff_t offset, u64 ino, unsigned int d_type) +static int listxattr_filler(void *buf, const char *name, int namelen, + loff_t offset, u64 ino, unsigned int d_type) { - struct reiserfs_listxattr_buf *b = (struct reiserfs_listxattr_buf *)buf; - int len = 0; - if (name[0] != '.' - || (namelen != 1 && (name[1] != '.' || namelen != 2))) { - struct reiserfs_xattr_handler *xah = - find_xattr_handler_prefix(name); - if (!xah) - return 0; /* Unsupported xattr name, skip it */ - - /* We call ->list() twice because the operation isn't required to just - * return the name back - we want to make sure we have enough space */ - len += xah->list(b->r_inode, name, namelen, NULL); - - if (len) { - if (b->r_pos + len + 1 <= b->r_size) { - char *p = b->r_buf + b->r_pos; - p += xah->list(b->r_inode, name, namelen, p); - *p++ = '\0'; - } - b->r_pos += len + 1; + struct listxattr_buf *b = (struct listxattr_buf *)buf; + size_t size; + if (name[0] != '.' || + (namelen != 1 && (name[1] != '.' || namelen != 2))) { + struct xattr_handler *handler; + handler = find_xattr_handler_prefix(b->inode->i_sb->s_xattr, + name); + if (!handler) /* Unsupported xattr name */ + return 0; + if (b->buf) { + size = handler->list(b->inode, b->buf + b->pos, + b->size, name, namelen); + if (size > b->size) + return -ERANGE; + } else { + size = handler->list(b->inode, NULL, 0, name, namelen); } - } + b->pos += size; + } return 0; } /* * Inode operation listxattr() + * + * We totally ignore the generic listxattr here because it would be stupid + * not to. Since the xattrs are organized in a directory, we can just + * readdir to find them. */ ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size) { struct dentry *dir; int err = 0; - struct reiserfs_listxattr_buf buf; + struct listxattr_buf buf = { + .inode = dentry->d_inode, + .buf = buffer, + .size = buffer ? size : 0, + }; if (!dentry->d_inode) return -EINVAL; @@ -985,120 +1000,22 @@ ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size) if (IS_ERR(dir)) { err = PTR_ERR(dir); if (err == -ENODATA) - err = 0; /* Not an error if there aren't any xattrs */ + err = 0; /* Not an error if there aren't any xattrs */ goto out; } - buf.r_buf = buffer; - buf.r_size = buffer ? size : 0; - buf.r_pos = 0; - buf.r_inode = dentry->d_inode; - mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_XATTR); - err = xattr_readdir(dir->d_inode, reiserfs_listxattr_filler, &buf); + err = xattr_readdir(dir->d_inode, listxattr_filler, &buf); mutex_unlock(&dir->d_inode->i_mutex); - if (!err) { - if (buf.r_pos > buf.r_size && buffer != NULL) - err = -ERANGE; - else - err = buf.r_pos; - } + if (!err) + err = buf.pos; dput(dir); out: return err; } -/* This is the implementation for the xattr plugin infrastructure */ -static LIST_HEAD(xattr_handlers); -static DEFINE_RWLOCK(handler_lock); - -static struct reiserfs_xattr_handler *find_xattr_handler_prefix(const char - *prefix) -{ - struct reiserfs_xattr_handler *xah = NULL; - struct list_head *p; - - read_lock(&handler_lock); - list_for_each(p, &xattr_handlers) { - xah = list_entry(p, struct reiserfs_xattr_handler, handlers); - if (strncmp(xah->prefix, prefix, strlen(xah->prefix)) == 0) - break; - xah = NULL; - } - - read_unlock(&handler_lock); - return xah; -} - -static void __unregister_handlers(void) -{ - struct reiserfs_xattr_handler *xah; - struct list_head *p, *tmp; - - list_for_each_safe(p, tmp, &xattr_handlers) { - xah = list_entry(p, struct reiserfs_xattr_handler, handlers); - if (xah->exit) - xah->exit(); - - list_del_init(p); - } - INIT_LIST_HEAD(&xattr_handlers); -} - -int __init reiserfs_xattr_register_handlers(void) -{ - int err = 0; - struct reiserfs_xattr_handler *xah; - struct list_head *p; - - write_lock(&handler_lock); - - /* If we're already initialized, nothing to do */ - if (!list_empty(&xattr_handlers)) { - write_unlock(&handler_lock); - return 0; - } - - /* Add the handlers */ - list_add_tail(&user_handler.handlers, &xattr_handlers); - list_add_tail(&trusted_handler.handlers, &xattr_handlers); -#ifdef CONFIG_REISERFS_FS_SECURITY - list_add_tail(&security_handler.handlers, &xattr_handlers); -#endif -#ifdef CONFIG_REISERFS_FS_POSIX_ACL - list_add_tail(&posix_acl_access_handler.handlers, &xattr_handlers); - list_add_tail(&posix_acl_default_handler.handlers, &xattr_handlers); -#endif - - /* Run initializers, if available */ - list_for_each(p, &xattr_handlers) { - xah = list_entry(p, struct reiserfs_xattr_handler, handlers); - if (xah->init) { - err = xah->init(); - if (err) { - list_del_init(p); - break; - } - } - } - - /* Clean up other handlers, if any failed */ - if (err) - __unregister_handlers(); - - write_unlock(&handler_lock); - return err; -} - -void reiserfs_xattr_unregister_handlers(void) -{ - write_lock(&handler_lock); - __unregister_handlers(); - write_unlock(&handler_lock); -} - static int reiserfs_check_acl(struct inode *inode, int mask) { struct posix_acl *acl; @@ -1157,20 +1074,16 @@ static int xattr_mount_check(struct super_block *s) { /* We need generation numbers to ensure that the oid mapping is correct * v3.5 filesystems don't have them. */ - if (!old_format_only(s)) { - set_bit(REISERFS_XATTRS, &(REISERFS_SB(s)->s_mount_opt)); - } else if (reiserfs_xattrs_optional(s)) { - /* Old format filesystem, but optional xattrs have been enabled - * at mount time. Error out. */ - reiserfs_warning(s, "jdm-20005", - "xattrs/ACLs not supported on pre v3.6 " - "format filesystem. Failing mount."); - return -EOPNOTSUPP; - } else { - /* Old format filesystem, but no optional xattrs have - * been enabled. This means we silently disable xattrs - * on the filesystem. */ - clear_bit(REISERFS_XATTRS, &(REISERFS_SB(s)->s_mount_opt)); + if (old_format_only(s)) { + if (reiserfs_xattrs_optional(s)) { + /* Old format filesystem, but optional xattrs have + * been enabled. Error out. */ + reiserfs_warning(s, "jdm-2005", + "xattrs/ACLs not supported " + "on pre-v3.6 format filesystems. " + "Failing mount."); + return -EOPNOTSUPP; + } } return 0; @@ -1251,9 +1164,11 @@ int reiserfs_xattr_init(struct super_block *s, int mount_flags) } #ifdef CONFIG_REISERFS_FS_XATTR + if (!err) + s->s_xattr = reiserfs_xattr_handlers; + error: if (err) { - clear_bit(REISERFS_XATTRS, &(REISERFS_SB(s)->s_mount_opt)); clear_bit(REISERFS_XATTRS_USER, &(REISERFS_SB(s)->s_mount_opt)); clear_bit(REISERFS_POSIXACL, &(REISERFS_SB(s)->s_mount_opt)); } diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c index d3ce6ee9b262..bfecf7553002 100644 --- a/fs/reiserfs/xattr_acl.c +++ b/fs/reiserfs/xattr_acl.c @@ -271,7 +271,7 @@ reiserfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) char *name; void *value = NULL; struct posix_acl **p_acl; - size_t size; + size_t size = 0; int error; struct reiserfs_inode_info *reiserfs_i = REISERFS_I(inode); @@ -308,16 +308,21 @@ reiserfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) value = posix_acl_to_disk(acl, &size); if (IS_ERR(value)) return (int)PTR_ERR(value); - error = reiserfs_xattr_set(inode, name, value, size, 0); - } else { - error = reiserfs_xattr_del(inode, name); - if (error == -ENODATA) { - /* This may seem odd here, but it means that the ACL was set - * with a value representable with mode bits. If there was - * an ACL before, reiserfs_xattr_del already dirtied the inode. - */ + } + + error = __reiserfs_xattr_set(inode, name, value, size, 0); + + /* + * Ensure that the inode gets dirtied if we're only using + * the mode bits and an old ACL didn't exist. We don't need + * to check if the inode is hashed here since we won't get + * called by reiserfs_inherit_default_acl(). + */ + if (error == -ENODATA) { + error = 0; + if (type == ACL_TYPE_ACCESS) { + inode->i_ctime = CURRENT_TIME_SEC; mark_inode_dirty(inode); - error = 0; } } @@ -474,33 +479,22 @@ posix_acl_access_set(struct inode *inode, const char *name, return xattr_set_acl(inode, ACL_TYPE_ACCESS, value, size); } -static int posix_acl_access_del(struct inode *inode, const char *name) -{ - struct reiserfs_inode_info *reiserfs_i = REISERFS_I(inode); - if (strlen(name) != sizeof(POSIX_ACL_XATTR_ACCESS) - 1) - return -EINVAL; - iset_acl(inode, &reiserfs_i->i_acl_access, ERR_PTR(-ENODATA)); - return 0; -} - -static int -posix_acl_access_list(struct inode *inode, const char *name, int namelen, - char *out) +static size_t posix_acl_access_list(struct inode *inode, char *list, + size_t list_size, const char *name, + size_t name_len) { - int len = namelen; + const size_t size = sizeof(POSIX_ACL_XATTR_ACCESS); if (!reiserfs_posixacl(inode->i_sb)) return 0; - if (out) - memcpy(out, name, len); - - return len; + if (list && size <= list_size) + memcpy(list, POSIX_ACL_XATTR_ACCESS, size); + return size; } -struct reiserfs_xattr_handler posix_acl_access_handler = { +struct xattr_handler reiserfs_posix_acl_access_handler = { .prefix = POSIX_ACL_XATTR_ACCESS, .get = posix_acl_access_get, .set = posix_acl_access_set, - .del = posix_acl_access_del, .list = posix_acl_access_list, }; @@ -522,32 +516,21 @@ posix_acl_default_set(struct inode *inode, const char *name, return xattr_set_acl(inode, ACL_TYPE_DEFAULT, value, size); } -static int posix_acl_default_del(struct inode *inode, const char *name) +static size_t posix_acl_default_list(struct inode *inode, char *list, + size_t list_size, const char *name, + size_t name_len) { - struct reiserfs_inode_info *reiserfs_i = REISERFS_I(inode); - if (strlen(name) != sizeof(POSIX_ACL_XATTR_DEFAULT) - 1) - return -EINVAL; - iset_acl(inode, &reiserfs_i->i_acl_default, ERR_PTR(-ENODATA)); - return 0; -} - -static int -posix_acl_default_list(struct inode *inode, const char *name, int namelen, - char *out) -{ - int len = namelen; + const size_t size = sizeof(POSIX_ACL_XATTR_DEFAULT); if (!reiserfs_posixacl(inode->i_sb)) return 0; - if (out) - memcpy(out, name, len); - - return len; + if (list && size <= list_size) + memcpy(list, POSIX_ACL_XATTR_DEFAULT, size); + return size; } -struct reiserfs_xattr_handler posix_acl_default_handler = { +struct xattr_handler reiserfs_posix_acl_default_handler = { .prefix = POSIX_ACL_XATTR_DEFAULT, .get = posix_acl_default_get, .set = posix_acl_default_set, - .del = posix_acl_default_del, .list = posix_acl_default_list, }; diff --git a/fs/reiserfs/xattr_security.c b/fs/reiserfs/xattr_security.c index 1958b361c35d..2aacf1fe69fd 100644 --- a/fs/reiserfs/xattr_security.c +++ b/fs/reiserfs/xattr_security.c @@ -31,35 +31,25 @@ security_set(struct inode *inode, const char *name, const void *buffer, return reiserfs_xattr_set(inode, name, buffer, size, flags); } -static int security_del(struct inode *inode, const char *name) +static size_t security_list(struct inode *inode, char *list, size_t list_len, + const char *name, size_t namelen) { - if (strlen(name) < sizeof(XATTR_SECURITY_PREFIX)) - return -EINVAL; - - if (IS_PRIVATE(inode)) - return -EPERM; - - return 0; -} - -static int -security_list(struct inode *inode, const char *name, int namelen, char *out) -{ - int len = namelen; + const size_t len = namelen + 1; if (IS_PRIVATE(inode)) return 0; - if (out) - memcpy(out, name, len); + if (list && len <= list_len) { + memcpy(list, name, namelen); + list[namelen] = '\0'; + } return len; } -struct reiserfs_xattr_handler security_handler = { +struct xattr_handler reiserfs_xattr_security_handler = { .prefix = XATTR_SECURITY_PREFIX, .get = security_get, .set = security_set, - .del = security_del, .list = security_list, }; diff --git a/fs/reiserfs/xattr_trusted.c b/fs/reiserfs/xattr_trusted.c index 076ad388d489..a865042f75e2 100644 --- a/fs/reiserfs/xattr_trusted.c +++ b/fs/reiserfs/xattr_trusted.c @@ -13,10 +13,7 @@ trusted_get(struct inode *inode, const char *name, void *buffer, size_t size) if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX)) return -EINVAL; - if (!reiserfs_xattrs(inode->i_sb)) - return -EOPNOTSUPP; - - if (!(capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode))) + if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode)) return -EPERM; return reiserfs_xattr_get(inode, name, buffer, size); @@ -29,50 +26,30 @@ trusted_set(struct inode *inode, const char *name, const void *buffer, if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX)) return -EINVAL; - if (!reiserfs_xattrs(inode->i_sb)) - return -EOPNOTSUPP; - - if (!(capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode))) + if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode)) return -EPERM; return reiserfs_xattr_set(inode, name, buffer, size, flags); } -static int trusted_del(struct inode *inode, const char *name) +static size_t trusted_list(struct inode *inode, char *list, size_t list_size, + const char *name, size_t name_len) { - if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX)) - return -EINVAL; + const size_t len = name_len + 1; - if (!reiserfs_xattrs(inode->i_sb)) - return -EOPNOTSUPP; - - if (!(capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode))) - return -EPERM; - - return 0; -} - -static int -trusted_list(struct inode *inode, const char *name, int namelen, char *out) -{ - int len = namelen; - - if (!reiserfs_xattrs(inode->i_sb)) + if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode)) return 0; - if (!(capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode))) - return 0; - - if (out) - memcpy(out, name, len); - + if (list && len <= list_size) { + memcpy(list, name, name_len); + list[name_len] = '\0'; + } return len; } -struct reiserfs_xattr_handler trusted_handler = { +struct xattr_handler reiserfs_xattr_trusted_handler = { .prefix = XATTR_TRUSTED_PREFIX, .get = trusted_get, .set = trusted_set, - .del = trusted_del, .list = trusted_list, }; diff --git a/fs/reiserfs/xattr_user.c b/fs/reiserfs/xattr_user.c index 1384efcb938e..e3238dc4f3db 100644 --- a/fs/reiserfs/xattr_user.c +++ b/fs/reiserfs/xattr_user.c @@ -6,10 +6,6 @@ #include #include -#ifdef CONFIG_REISERFS_FS_POSIX_ACL -# include -#endif - static int user_get(struct inode *inode, const char *name, void *buffer, size_t size) { @@ -25,7 +21,6 @@ static int user_set(struct inode *inode, const char *name, const void *buffer, size_t size, int flags) { - if (strlen(name) < sizeof(XATTR_USER_PREFIX)) return -EINVAL; @@ -34,33 +29,23 @@ user_set(struct inode *inode, const char *name, const void *buffer, return reiserfs_xattr_set(inode, name, buffer, size, flags); } -static int user_del(struct inode *inode, const char *name) +static size_t user_list(struct inode *inode, char *list, size_t list_size, + const char *name, size_t name_len) { - if (strlen(name) < sizeof(XATTR_USER_PREFIX)) - return -EINVAL; - - if (!reiserfs_xattrs_user(inode->i_sb)) - return -EOPNOTSUPP; - return 0; -} + const size_t len = name_len + 1; -static int -user_list(struct inode *inode, const char *name, int namelen, char *out) -{ - int len = namelen; if (!reiserfs_xattrs_user(inode->i_sb)) return 0; - - if (out) - memcpy(out, name, len); - + if (list && len <= list_size) { + memcpy(list, name, name_len); + list[name_len] = '\0'; + } return len; } -struct reiserfs_xattr_handler user_handler = { +struct xattr_handler reiserfs_xattr_user_handler = { .prefix = XATTR_USER_PREFIX, .get = user_get, .set = user_set, - .del = user_del, .list = user_list, }; diff --git a/include/linux/reiserfs_acl.h b/include/linux/reiserfs_acl.h index fe00f781a622..d180446470f2 100644 --- a/include/linux/reiserfs_acl.h +++ b/include/linux/reiserfs_acl.h @@ -52,10 +52,8 @@ int reiserfs_acl_chmod(struct inode *inode); int reiserfs_inherit_default_acl(struct inode *dir, struct dentry *dentry, struct inode *inode); int reiserfs_cache_default_acl(struct inode *dir); -extern int reiserfs_xattr_posix_acl_init(void) __init; -extern int reiserfs_xattr_posix_acl_exit(void); -extern struct reiserfs_xattr_handler posix_acl_default_handler; -extern struct reiserfs_xattr_handler posix_acl_access_handler; +extern struct xattr_handler reiserfs_posix_acl_default_handler; +extern struct xattr_handler reiserfs_posix_acl_access_handler; static inline void reiserfs_init_acl_access(struct inode *inode) { @@ -75,16 +73,6 @@ static inline struct posix_acl *reiserfs_get_acl(struct inode *inode, int type) return NULL; } -static inline int reiserfs_xattr_posix_acl_init(void) -{ - return 0; -} - -static inline int reiserfs_xattr_posix_acl_exit(void) -{ - return 0; -} - static inline int reiserfs_acl_chmod(struct inode *inode) { return 0; diff --git a/include/linux/reiserfs_fs_sb.h b/include/linux/reiserfs_fs_sb.h index c8aee41ccc23..4686b90886ed 100644 --- a/include/linux/reiserfs_fs_sb.h +++ b/include/linux/reiserfs_fs_sb.h @@ -451,7 +451,6 @@ enum reiserfs_mount_options { REISERFS_NO_UNHASHED_RELOCATION, REISERFS_HASHED_RELOCATION, REISERFS_ATTRS, - REISERFS_XATTRS, REISERFS_XATTRS_USER, REISERFS_POSIXACL, REISERFS_BARRIER_NONE, @@ -489,7 +488,7 @@ enum reiserfs_mount_options { #define reiserfs_data_log(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_DATA_LOG)) #define reiserfs_data_ordered(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_DATA_ORDERED)) #define reiserfs_data_writeback(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_DATA_WRITEBACK)) -#define reiserfs_xattrs(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_XATTRS)) +#define reiserfs_xattrs(s) ((s)->s_xattr != NULL) #define reiserfs_xattrs_user(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_XATTRS_USER)) #define reiserfs_posixacl(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_POSIXACL)) #define reiserfs_xattrs_optional(s) (reiserfs_xattrs_user(s) || reiserfs_posixacl(s)) diff --git a/include/linux/reiserfs_xattr.h b/include/linux/reiserfs_xattr.h index 3bd154fd56e9..958fcaca0e8b 100644 --- a/include/linux/reiserfs_xattr.h +++ b/include/linux/reiserfs_xattr.h @@ -29,20 +29,6 @@ struct iattr; struct super_block; struct nameidata; -struct reiserfs_xattr_handler { - char *prefix; - int (*init) (void); - void (*exit) (void); - int (*get) (struct inode * inode, const char *name, void *buffer, - size_t size); - int (*set) (struct inode * inode, const char *name, const void *buffer, - size_t size, int flags); - int (*del) (struct inode * inode, const char *name); - int (*list) (struct inode * inode, const char *name, int namelen, - char *out); - struct list_head handlers; -}; - int reiserfs_xattr_register_handlers(void) __init; void reiserfs_xattr_unregister_handlers(void); int reiserfs_xattr_init(struct super_block *sb, int mount_flags); @@ -59,13 +45,14 @@ ssize_t reiserfs_listxattr(struct dentry *dentry, char *buffer, size_t size); int reiserfs_removexattr(struct dentry *dentry, const char *name); int reiserfs_permission(struct inode *inode, int mask); -int reiserfs_xattr_del(struct inode *, const char *); -int reiserfs_xattr_get(const struct inode *, const char *, void *, size_t); +int reiserfs_xattr_get(struct inode *, const char *, void *, size_t); +int __reiserfs_xattr_set(struct inode *, const char *, const void *, + size_t, int); int reiserfs_xattr_set(struct inode *, const char *, const void *, size_t, int); -extern struct reiserfs_xattr_handler user_handler; -extern struct reiserfs_xattr_handler trusted_handler; -extern struct reiserfs_xattr_handler security_handler; +extern struct xattr_handler reiserfs_xattr_user_handler; +extern struct xattr_handler reiserfs_xattr_trusted_handler; +extern struct xattr_handler reiserfs_xattr_security_handler; static inline void reiserfs_init_xattr_rwsem(struct inode *inode) { -- cgit v1.2.3 From 0ab2621ebd9a28bf7a524ecd50d492a10579dfcc Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Mon, 30 Mar 2009 14:02:39 -0400 Subject: reiserfs: journaled xattrs Deadlocks are possible in the xattr code between the journal lock and the xattr sems. This patch implements journalling for xattr operations. The benefit is twofold: * It gets rid of the deadlock possibility by always ensuring that xattr write operations are initiated inside a transaction. * It corrects the problem where xattr backing files aren't considered any differently than normal files, despite the fact they are metadata. I discussed the added journal load with Chris Mason, and we decided that since xattrs (versus other journal activity) is fairly rare, the introduction of larger transactions to support journaled xattrs wouldn't be too big a deal. Signed-off-by: Jeff Mahoney Signed-off-by: Linus Torvalds --- fs/reiserfs/inode.c | 3 +- fs/reiserfs/namei.c | 14 ++---- fs/reiserfs/xattr.c | 39 +++++++++++---- fs/reiserfs/xattr_acl.c | 105 +++++++++++++++++++++++++++++++---------- include/linux/reiserfs_acl.h | 3 +- include/linux/reiserfs_fs.h | 4 ++ include/linux/reiserfs_xattr.h | 40 +++++++++++++++- 7 files changed, 159 insertions(+), 49 deletions(-) (limited to 'fs/reiserfs/xattr.c') diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 50a73e7afdc8..995f6975cae1 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c @@ -1914,9 +1914,8 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, goto out_inserted_sd; } - /* XXX CHECK THIS */ if (reiserfs_posixacl(inode->i_sb)) { - retval = reiserfs_inherit_default_acl(dir, dentry, inode); + retval = reiserfs_inherit_default_acl(th, dir, dentry, inode); if (retval) { err = retval; reiserfs_check_path(&path_to_key); diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index ddf1bcd41c87..d9c1c8bd2950 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c @@ -598,15 +598,13 @@ static int reiserfs_create(struct inode *dir, struct dentry *dentry, int mode, 2 * (REISERFS_QUOTA_INIT_BLOCKS(dir->i_sb) + REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb)); struct reiserfs_transaction_handle th; - int locked; if (!(inode = new_inode(dir->i_sb))) { return -ENOMEM; } new_inode_init(inode, dir, mode); - locked = reiserfs_cache_default_acl(dir); - + jbegin_count += reiserfs_cache_default_acl(dir); reiserfs_write_lock(dir->i_sb); retval = journal_begin(&th, dir->i_sb, jbegin_count); @@ -662,7 +660,6 @@ static int reiserfs_mknod(struct inode *dir, struct dentry *dentry, int mode, JOURNAL_PER_BALANCE_CNT * 3 + 2 * (REISERFS_QUOTA_INIT_BLOCKS(dir->i_sb) + REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb)); - int locked; if (!new_valid_dev(rdev)) return -EINVAL; @@ -672,8 +669,7 @@ static int reiserfs_mknod(struct inode *dir, struct dentry *dentry, int mode, } new_inode_init(inode, dir, mode); - locked = reiserfs_cache_default_acl(dir); - + jbegin_count += reiserfs_cache_default_acl(dir); reiserfs_write_lock(dir->i_sb); retval = journal_begin(&th, dir->i_sb, jbegin_count); @@ -732,7 +728,6 @@ static int reiserfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) JOURNAL_PER_BALANCE_CNT * 3 + 2 * (REISERFS_QUOTA_INIT_BLOCKS(dir->i_sb) + REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb)); - int locked; #ifdef DISPLACE_NEW_PACKING_LOCALITIES /* set flag that new packing locality created and new blocks for the content * of that directory are not displaced yet */ @@ -744,8 +739,7 @@ static int reiserfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) } new_inode_init(inode, dir, mode); - locked = reiserfs_cache_default_acl(dir); - + jbegin_count += reiserfs_cache_default_acl(dir); reiserfs_write_lock(dir->i_sb); retval = journal_begin(&th, dir->i_sb, jbegin_count); @@ -1034,8 +1028,6 @@ static int reiserfs_symlink(struct inode *parent_dir, memcpy(name, symname, strlen(symname)); padd_item(name, item_len, strlen(symname)); - /* We would inherit the default ACL here, but symlinks don't get ACLs */ - retval = journal_begin(&th, parent_dir->i_sb, jbegin_count); if (retval) { drop_new_inode(inode); diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index d3ce27436605..c2e3a92aaf2b 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c @@ -632,8 +632,9 @@ out_dput: * inode->i_mutex: down */ int -__reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, - size_t buffer_size, int flags) +reiserfs_xattr_set_handle(struct reiserfs_transaction_handle *th, + struct inode *inode, const char *name, + const void *buffer, size_t buffer_size, int flags) { int err = 0; struct dentry *dentry; @@ -723,14 +724,34 @@ out_unlock: return err; } -int -reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, - size_t buffer_size, int flags) +/* We need to start a transaction to maintain lock ordering */ +int reiserfs_xattr_set(struct inode *inode, const char *name, + const void *buffer, size_t buffer_size, int flags) { - int err = __reiserfs_xattr_set(inode, name, buffer, buffer_size, flags); - if (err == -ENODATA) - err = 0; - return err; + + struct reiserfs_transaction_handle th; + int error, error2; + size_t jbegin_count = reiserfs_xattr_nblocks(inode, buffer_size); + + if (!(flags & XATTR_REPLACE)) + jbegin_count += reiserfs_xattr_jcreate_nblocks(inode); + + reiserfs_write_lock(inode->i_sb); + error = journal_begin(&th, inode->i_sb, jbegin_count); + if (error) { + reiserfs_write_unlock(inode->i_sb); + return error; + } + + error = reiserfs_xattr_set_handle(&th, inode, name, + buffer, buffer_size, flags); + + error2 = journal_end(&th, inode->i_sb, jbegin_count); + if (error == 0) + error = error2; + reiserfs_write_unlock(inode->i_sb); + + return error; } /* diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c index bfecf7553002..d423416d93d1 100644 --- a/fs/reiserfs/xattr_acl.c +++ b/fs/reiserfs/xattr_acl.c @@ -10,15 +10,17 @@ #include #include -static int reiserfs_set_acl(struct inode *inode, int type, +static int reiserfs_set_acl(struct reiserfs_transaction_handle *th, + struct inode *inode, int type, struct posix_acl *acl); static int xattr_set_acl(struct inode *inode, int type, const void *value, size_t size) { struct posix_acl *acl; - int error; - + int error, error2; + struct reiserfs_transaction_handle th; + size_t jcreate_blocks; if (!reiserfs_posixacl(inode->i_sb)) return -EOPNOTSUPP; if (!is_owner_or_cap(inode)) @@ -36,7 +38,21 @@ xattr_set_acl(struct inode *inode, int type, const void *value, size_t size) } else acl = NULL; - error = reiserfs_set_acl(inode, type, acl); + /* Pessimism: We can't assume that anything from the xattr root up + * has been created. */ + + jcreate_blocks = reiserfs_xattr_jcreate_nblocks(inode) + + reiserfs_xattr_nblocks(inode, size) * 2; + + reiserfs_write_lock(inode->i_sb); + error = journal_begin(&th, inode->i_sb, jcreate_blocks); + if (error == 0) { + error = reiserfs_set_acl(&th, inode, type, acl); + error2 = journal_end(&th, inode->i_sb, jcreate_blocks); + if (error2) + error = error2; + } + reiserfs_write_unlock(inode->i_sb); release_and_out: posix_acl_release(acl); @@ -266,7 +282,8 @@ struct posix_acl *reiserfs_get_acl(struct inode *inode, int type) * BKL held [before 2.5.x] */ static int -reiserfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) +reiserfs_set_acl(struct reiserfs_transaction_handle *th, struct inode *inode, + int type, struct posix_acl *acl) { char *name; void *value = NULL; @@ -310,7 +327,7 @@ reiserfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) return (int)PTR_ERR(value); } - error = __reiserfs_xattr_set(inode, name, value, size, 0); + error = reiserfs_xattr_set_handle(th, inode, name, value, size, 0); /* * Ensure that the inode gets dirtied if we're only using @@ -337,7 +354,8 @@ reiserfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) /* dir->i_mutex: locked, * inode is new and not released into the wild yet */ int -reiserfs_inherit_default_acl(struct inode *dir, struct dentry *dentry, +reiserfs_inherit_default_acl(struct reiserfs_transaction_handle *th, + struct inode *dir, struct dentry *dentry, struct inode *inode) { struct posix_acl *acl; @@ -374,7 +392,8 @@ reiserfs_inherit_default_acl(struct inode *dir, struct dentry *dentry, /* Copy the default ACL to the default ACL of a new directory */ if (S_ISDIR(inode->i_mode)) { - err = reiserfs_set_acl(inode, ACL_TYPE_DEFAULT, acl); + err = reiserfs_set_acl(th, inode, ACL_TYPE_DEFAULT, + acl); if (err) goto cleanup; } @@ -395,9 +414,9 @@ reiserfs_inherit_default_acl(struct inode *dir, struct dentry *dentry, /* If we need an ACL.. */ if (need_acl > 0) { - err = - reiserfs_set_acl(inode, ACL_TYPE_ACCESS, - acl_copy); + err = reiserfs_set_acl(th, inode, + ACL_TYPE_ACCESS, + acl_copy); if (err) goto cleanup_copy; } @@ -415,21 +434,45 @@ reiserfs_inherit_default_acl(struct inode *dir, struct dentry *dentry, return err; } -/* Looks up and caches the result of the default ACL. - * We do this so that we don't need to carry the xattr_sem into - * reiserfs_new_inode if we don't need to */ +/* This is used to cache the default acl before a new object is created. + * The biggest reason for this is to get an idea of how many blocks will + * actually be required for the create operation if we must inherit an ACL. + * An ACL write can add up to 3 object creations and an additional file write + * so we'd prefer not to reserve that many blocks in the journal if we can. + * It also has the advantage of not loading the ACL with a transaction open, + * this may seem silly, but if the owner of the directory is doing the + * creation, the ACL may not be loaded since the permissions wouldn't require + * it. + * We return the number of blocks required for the transaction. + */ int reiserfs_cache_default_acl(struct inode *inode) { - int ret = 0; - if (reiserfs_posixacl(inode->i_sb) && !IS_PRIVATE(inode)) { - struct posix_acl *acl; - acl = reiserfs_get_acl(inode, ACL_TYPE_DEFAULT); - ret = (acl && !IS_ERR(acl)); - if (ret) - posix_acl_release(acl); + struct posix_acl *acl; + int nblocks = 0; + + if (IS_PRIVATE(inode)) + return 0; + + acl = reiserfs_get_acl(inode, ACL_TYPE_DEFAULT); + + if (acl && !IS_ERR(acl)) { + int size = reiserfs_acl_size(acl->a_count); + + /* Other xattrs can be created during inode creation. We don't + * want to claim too many blocks, so we check to see if we + * we need to create the tree to the xattrs, and then we + * just want two files. */ + nblocks = reiserfs_xattr_jcreate_nblocks(inode); + nblocks += JOURNAL_BLOCKS_PER_OBJECT(inode->i_sb); + + REISERFS_I(inode)->i_flags |= i_has_xattr_dir; + + /* We need to account for writes + bitmaps for two files */ + nblocks += reiserfs_xattr_nblocks(inode, size) * 4; + posix_acl_release(acl); } - return ret; + return nblocks; } int reiserfs_acl_chmod(struct inode *inode) @@ -455,8 +498,22 @@ int reiserfs_acl_chmod(struct inode *inode) if (!clone) return -ENOMEM; error = posix_acl_chmod_masq(clone, inode->i_mode); - if (!error) - error = reiserfs_set_acl(inode, ACL_TYPE_ACCESS, clone); + if (!error) { + struct reiserfs_transaction_handle th; + size_t size = reiserfs_xattr_nblocks(inode, + reiserfs_acl_size(clone->a_count)); + reiserfs_write_lock(inode->i_sb); + error = journal_begin(&th, inode->i_sb, size * 2); + if (!error) { + int error2; + error = reiserfs_set_acl(&th, inode, ACL_TYPE_ACCESS, + clone); + error2 = journal_end(&th, inode->i_sb, size * 2); + if (error2) + error = error2; + } + reiserfs_write_unlock(inode->i_sb); + } posix_acl_release(clone); return error; } diff --git a/include/linux/reiserfs_acl.h b/include/linux/reiserfs_acl.h index d180446470f2..52240e02de02 100644 --- a/include/linux/reiserfs_acl.h +++ b/include/linux/reiserfs_acl.h @@ -49,7 +49,8 @@ static inline int reiserfs_acl_count(size_t size) #ifdef CONFIG_REISERFS_FS_POSIX_ACL struct posix_acl *reiserfs_get_acl(struct inode *inode, int type); int reiserfs_acl_chmod(struct inode *inode); -int reiserfs_inherit_default_acl(struct inode *dir, struct dentry *dentry, +int reiserfs_inherit_default_acl(struct reiserfs_transaction_handle *th, + struct inode *dir, struct dentry *dentry, struct inode *inode); int reiserfs_cache_default_acl(struct inode *dir); extern struct xattr_handler reiserfs_posix_acl_default_handler; diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h index e00d240314c5..67ad310fa88b 100644 --- a/include/linux/reiserfs_fs.h +++ b/include/linux/reiserfs_fs.h @@ -1615,6 +1615,10 @@ struct reiserfs_journal_header { #define JOURNAL_MAX_COMMIT_AGE 30 #define JOURNAL_MAX_TRANS_AGE 30 #define JOURNAL_PER_BALANCE_CNT (3 * (MAX_HEIGHT-2) + 9) +#define JOURNAL_BLOCKS_PER_OBJECT(sb) (JOURNAL_PER_BALANCE_CNT * 3 + \ + 2 * (REISERFS_QUOTA_INIT_BLOCKS(sb) + \ + REISERFS_QUOTA_TRANS_BLOCKS(sb))) + #ifdef CONFIG_QUOTA /* We need to update data and inode (atime) */ #define REISERFS_QUOTA_TRANS_BLOCKS(s) (REISERFS_SB(s)->s_mount_opt & (1<i_sb->s_blocksize); + ret >>= inode->i_sb->s_blocksize_bits; + } + return ret; +} + +/* We may have to create up to 3 objects: xattr root, xattr dir, xattr file. + * Let's try to be smart about it. + * xattr root: We cache it. If it's not cached, we may need to create it. + * xattr dir: If anything has been loaded for this inode, we can set a flag + * saying so. + * xattr file: Since we don't cache xattrs, we can't tell. We always include + * blocks for it. + * + * However, since root and dir can be created between calls - YOU MUST SAVE + * THIS VALUE. + */ +static inline size_t reiserfs_xattr_jcreate_nblocks(struct inode *inode) +{ + size_t nblocks = JOURNAL_BLOCKS_PER_OBJECT(inode->i_sb); + + if ((REISERFS_I(inode)->i_flags & i_has_xattr_dir) == 0) { + nblocks += JOURNAL_BLOCKS_PER_OBJECT(inode->i_sb); + if (REISERFS_SB(inode->i_sb)->xattr_root == NULL) + nblocks += JOURNAL_BLOCKS_PER_OBJECT(inode->i_sb); + } + + return nblocks; +} + static inline void reiserfs_init_xattr_rwsem(struct inode *inode) { init_rwsem(&REISERFS_I(inode)->i_xattr_sem); -- cgit v1.2.3 From a41f1a4715f26f7bc4d047d0bc7710145c8e69c7 Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Mon, 30 Mar 2009 14:02:40 -0400 Subject: reiserfs: use generic readdir for operations across all xattrs The current reiserfs xattr implementation open codes reiserfs_readdir and frees the path before calling the filldir function. Typically, the filldir function is something that modifies the file system, such as a chown or an inode deletion that also require reading of an inode associated with each direntry. Since the file system is modified, the path retained becomes invalid for the next run. In addition, it runs backwards in attempt to minimize activity. This is clearly suboptimal from a code cleanliness perspective as well as performance-wise. This patch implements a generic reiserfs_for_each_xattr that uses the generic readdir and a specific filldir routine that simply populates an array of dentries and then performs a specific operation on them. When all files have been operated on, it then calls the operation on the directory itself. The result is a noticable code reduction and better performance. Signed-off-by: Jeff Mahoney Signed-off-by: Linus Torvalds --- fs/reiserfs/dir.c | 28 +-- fs/reiserfs/xattr.c | 402 +++++++++++++------------------------------- include/linux/reiserfs_fs.h | 1 + 3 files changed, 131 insertions(+), 300 deletions(-) (limited to 'fs/reiserfs/xattr.c') diff --git a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c index e6b03d2020c1..67a80d7e59e2 100644 --- a/fs/reiserfs/dir.c +++ b/fs/reiserfs/dir.c @@ -41,10 +41,10 @@ static int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry, #define store_ih(where,what) copy_item_head (where, what) -// -static int reiserfs_readdir(struct file *filp, void *dirent, filldir_t filldir) +int reiserfs_readdir_dentry(struct dentry *dentry, void *dirent, + filldir_t filldir, loff_t *pos) { - struct inode *inode = filp->f_path.dentry->d_inode; + struct inode *inode = dentry->d_inode; struct cpu_key pos_key; /* key of current position in the directory (key of directory entry) */ INITIALIZE_PATH(path_to_entry); struct buffer_head *bh; @@ -64,13 +64,9 @@ static int reiserfs_readdir(struct file *filp, void *dirent, filldir_t filldir) /* form key for search the next directory entry using f_pos field of file structure */ - make_cpu_key(&pos_key, inode, - (filp->f_pos) ? (filp->f_pos) : DOT_OFFSET, TYPE_DIRENTRY, - 3); + make_cpu_key(&pos_key, inode, *pos ?: DOT_OFFSET, TYPE_DIRENTRY, 3); next_pos = cpu_key_k_offset(&pos_key); - /* reiserfs_warning (inode->i_sb, "reiserfs_readdir 1: f_pos = %Ld", filp->f_pos); */ - path_to_entry.reada = PATH_READA; while (1) { research: @@ -144,7 +140,7 @@ static int reiserfs_readdir(struct file *filp, void *dirent, filldir_t filldir) /* Ignore the .reiserfs_priv entry */ if (reiserfs_xattrs(inode->i_sb) && !old_format_only(inode->i_sb) && - filp->f_path.dentry == inode->i_sb->s_root && + dentry == inode->i_sb->s_root && REISERFS_SB(inode->i_sb)->priv_root && REISERFS_SB(inode->i_sb)->priv_root->d_inode && deh_objectid(deh) == @@ -156,7 +152,7 @@ static int reiserfs_readdir(struct file *filp, void *dirent, filldir_t filldir) } d_off = deh_offset(deh); - filp->f_pos = d_off; + *pos = d_off; d_ino = deh_objectid(deh); if (d_reclen <= 32) { local_buf = small_buf; @@ -223,15 +219,21 @@ static int reiserfs_readdir(struct file *filp, void *dirent, filldir_t filldir) } /* while */ - end: - filp->f_pos = next_pos; +end: + *pos = next_pos; pathrelse(&path_to_entry); reiserfs_check_path(&path_to_entry); - out: +out: reiserfs_write_unlock(inode->i_sb); return ret; } +static int reiserfs_readdir(struct file *file, void *dirent, filldir_t filldir) +{ + struct dentry *dentry = file->f_path.dentry; + return reiserfs_readdir_dentry(dentry, dirent, filldir, &file->f_pos); +} + /* compose directory item containing "." and ".." entries (entries are not aligned to 4 byte boundary) */ /* the last four params are LE */ diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index c2e3a92aaf2b..1baafec64331 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c @@ -167,218 +167,65 @@ static struct dentry *open_xa_dir(const struct inode *inode, int flags) } -/* - * this is very similar to fs/reiserfs/dir.c:reiserfs_readdir, but - * we need to drop the path before calling the filldir struct. That - * would be a big performance hit to the non-xattr case, so I've copied - * the whole thing for now. --clm - * - * the big difference is that I go backwards through the directory, - * and don't mess with f->f_pos, but the idea is the same. Do some - * action on each and every entry in the directory. - * - * we're called with i_mutex held, so there are no worries about the directory - * changing underneath us. - */ -static int __xattr_readdir(struct inode *inode, void *dirent, filldir_t filldir) -{ - struct cpu_key pos_key; /* key of current position in the directory (key of directory entry) */ - INITIALIZE_PATH(path_to_entry); - struct buffer_head *bh; - int entry_num; - struct item_head *ih, tmp_ih; - int search_res; - char *local_buf; - loff_t next_pos; - char small_buf[32]; /* avoid kmalloc if we can */ - struct reiserfs_de_head *deh; - int d_reclen; - char *d_name; - off_t d_off; - ino_t d_ino; - struct reiserfs_dir_entry de; - - /* form key for search the next directory entry using f_pos field of - file structure */ - next_pos = max_reiserfs_offset(inode); - - while (1) { - research: - if (next_pos <= DOT_DOT_OFFSET) - break; - make_cpu_key(&pos_key, inode, next_pos, TYPE_DIRENTRY, 3); - - search_res = - search_by_entry_key(inode->i_sb, &pos_key, &path_to_entry, - &de); - if (search_res == IO_ERROR) { - // FIXME: we could just skip part of directory which could - // not be read - pathrelse(&path_to_entry); - return -EIO; - } - - if (search_res == NAME_NOT_FOUND) - de.de_entry_num--; - - set_de_name_and_namelen(&de); - entry_num = de.de_entry_num; - deh = &(de.de_deh[entry_num]); - - bh = de.de_bh; - ih = de.de_ih; - - if (!is_direntry_le_ih(ih)) { - reiserfs_error(inode->i_sb, "jdm-20000", - "not direntry %h", ih); - break; - } - copy_item_head(&tmp_ih, ih); - - /* we must have found item, that is item of this directory, */ - RFALSE(COMP_SHORT_KEYS(&(ih->ih_key), &pos_key), - "vs-9000: found item %h does not match to dir we readdir %K", - ih, &pos_key); - - if (deh_offset(deh) <= DOT_DOT_OFFSET) { - break; - } - - /* look for the previous entry in the directory */ - next_pos = deh_offset(deh) - 1; - - if (!de_visible(deh)) - /* it is hidden entry */ - continue; - - d_reclen = entry_length(bh, ih, entry_num); - d_name = B_I_DEH_ENTRY_FILE_NAME(bh, ih, deh); - d_off = deh_offset(deh); - d_ino = deh_objectid(deh); - - if (!d_name[d_reclen - 1]) - d_reclen = strlen(d_name); - - if (d_reclen > REISERFS_MAX_NAME(inode->i_sb->s_blocksize)) { - /* too big to send back to VFS */ - continue; - } - - /* Ignore the .reiserfs_priv entry */ - if (reiserfs_xattrs(inode->i_sb) && - !old_format_only(inode->i_sb) && - deh_objectid(deh) == - le32_to_cpu(INODE_PKEY - (REISERFS_SB(inode->i_sb)->priv_root->d_inode)-> - k_objectid)) - continue; - - if (d_reclen <= 32) { - local_buf = small_buf; - } else { - local_buf = kmalloc(d_reclen, GFP_NOFS); - if (!local_buf) { - pathrelse(&path_to_entry); - return -ENOMEM; - } - if (item_moved(&tmp_ih, &path_to_entry)) { - kfree(local_buf); - - /* sigh, must retry. Do this same offset again */ - next_pos = d_off; - goto research; - } - } - - // Note, that we copy name to user space via temporary - // buffer (local_buf) because filldir will block if - // user space buffer is swapped out. At that time - // entry can move to somewhere else - memcpy(local_buf, d_name, d_reclen); - - /* the filldir function might need to start transactions, - * or do who knows what. Release the path now that we've - * copied all the important stuff out of the deh - */ - pathrelse(&path_to_entry); - - if (filldir(dirent, local_buf, d_reclen, d_off, d_ino, - DT_UNKNOWN) < 0) { - if (local_buf != small_buf) { - kfree(local_buf); - } - goto end; - } - if (local_buf != small_buf) { - kfree(local_buf); - } - } /* while */ - - end: - pathrelse(&path_to_entry); - return 0; -} - -/* - * this could be done with dedicated readdir ops for the xattr files, - * but I want to get something working asap - * this is stolen from vfs_readdir - * - */ -static -int xattr_readdir(struct inode *inode, filldir_t filler, void *buf) -{ - int res = -ENOENT; - if (!IS_DEADDIR(inode)) { - lock_kernel(); - res = __xattr_readdir(inode, buf, filler); - unlock_kernel(); - } - return res; -} - /* The following are side effects of other operations that aren't explicitly * modifying extended attributes. This includes operations such as permissions * or ownership changes, object deletions, etc. */ +struct reiserfs_dentry_buf { + struct dentry *xadir; + int count; + struct dentry *dentries[8]; +}; static int -reiserfs_delete_xattrs_filler(void *buf, const char *name, int namelen, - loff_t offset, u64 ino, unsigned int d_type) +fill_with_dentries(void *buf, const char *name, int namelen, loff_t offset, + u64 ino, unsigned int d_type) { - struct dentry *xadir = (struct dentry *)buf; + struct reiserfs_dentry_buf *dbuf = buf; struct dentry *dentry; - int err = 0; - dentry = lookup_one_len(name, xadir, namelen); + if (dbuf->count == ARRAY_SIZE(dbuf->dentries)) + return -ENOSPC; + + if (name[0] == '.' && (name[1] == '\0' || + (name[1] == '.' && name[2] == '\0'))) + return 0; + + dentry = lookup_one_len(name, dbuf->xadir, namelen); if (IS_ERR(dentry)) { - err = PTR_ERR(dentry); - goto out; + return PTR_ERR(dentry); } else if (!dentry->d_inode) { - err = -ENODATA; - goto out_file; + /* A directory entry exists, but no file? */ + reiserfs_error(dentry->d_sb, "xattr-20003", + "Corrupted directory: xattr %s listed but " + "not found for file %s.\n", + dentry->d_name.name, dbuf->xadir->d_name.name); + dput(dentry); + return -EIO; } - /* Skip directories.. */ - if (S_ISDIR(dentry->d_inode->i_mode)) - goto out_file; - - err = xattr_unlink(xadir->d_inode, dentry); - -out_file: - dput(dentry); + dbuf->dentries[dbuf->count++] = dentry; + return 0; +} -out: - return err; +static void +cleanup_dentry_buf(struct reiserfs_dentry_buf *buf) +{ + int i; + for (i = 0; i < buf->count; i++) + if (buf->dentries[i]) + dput(buf->dentries[i]); } -/* This is called w/ inode->i_mutex downed */ -int reiserfs_delete_xattrs(struct inode *inode) +static int reiserfs_for_each_xattr(struct inode *inode, + int (*action)(struct dentry *, void *), + void *data) { - int err = -ENODATA; - struct dentry *dir, *root; - struct reiserfs_transaction_handle th; - int blocks = JOURNAL_PER_BALANCE_CNT * 2 + 2 + - 4 * REISERFS_QUOTA_TRANS_BLOCKS(inode->i_sb); + struct dentry *dir; + int i, err = 0; + loff_t pos = 0; + struct reiserfs_dentry_buf buf = { + .count = 0, + }; /* Skip out, an xattr has no xattrs associated with it */ if (IS_PRIVATE(inode) || get_inode_sd_version(inode) == STAT_DATA_V1) @@ -389,117 +236,97 @@ int reiserfs_delete_xattrs(struct inode *inode) err = PTR_ERR(dir); goto out; } else if (!dir->d_inode) { - dput(dir); - goto out; + err = 0; + goto out_dir; } mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_XATTR); - err = xattr_readdir(dir->d_inode, reiserfs_delete_xattrs_filler, dir); - mutex_unlock(&dir->d_inode->i_mutex); - if (err) { - dput(dir); - goto out; + buf.xadir = dir; + err = reiserfs_readdir_dentry(dir, &buf, fill_with_dentries, &pos); + while ((err == 0 || err == -ENOSPC) && buf.count) { + err = 0; + + for (i = 0; i < buf.count && buf.dentries[i]; i++) { + int lerr = 0; + struct dentry *dentry = buf.dentries[i]; + + if (err == 0 && !S_ISDIR(dentry->d_inode->i_mode)) + lerr = action(dentry, data); + + dput(dentry); + buf.dentries[i] = NULL; + err = lerr ?: err; + } + buf.count = 0; + if (!err) + err = reiserfs_readdir_dentry(dir, &buf, + fill_with_dentries, &pos); } + mutex_unlock(&dir->d_inode->i_mutex); - root = dget(dir->d_parent); - dput(dir); + /* Clean up after a failed readdir */ + cleanup_dentry_buf(&buf); - /* We start a transaction here to avoid a ABBA situation - * between the xattr root's i_mutex and the journal lock. - * Inode creation will inherit an ACL, which requires a - * lookup. The lookup locks the xattr root i_mutex with a - * transaction open. Inode deletion takes teh xattr root - * i_mutex to delete the directory and then starts a - * transaction inside it. Boom. This doesn't incur much - * additional overhead since the reiserfs_rmdir transaction - * will just nest inside the outer transaction. */ - err = journal_begin(&th, inode->i_sb, blocks); if (!err) { - int jerror; - mutex_lock_nested(&root->d_inode->i_mutex, I_MUTEX_XATTR); - err = xattr_rmdir(root->d_inode, dir); - jerror = journal_end(&th, inode->i_sb, blocks); - mutex_unlock(&root->d_inode->i_mutex); - err = jerror ?: err; + /* We start a transaction here to avoid a ABBA situation + * between the xattr root's i_mutex and the journal lock. + * This doesn't incur much additional overhead since the + * new transaction will just nest inside the + * outer transaction. */ + int blocks = JOURNAL_PER_BALANCE_CNT * 2 + 2 + + 4 * REISERFS_QUOTA_TRANS_BLOCKS(inode->i_sb); + struct reiserfs_transaction_handle th; + err = journal_begin(&th, inode->i_sb, blocks); + if (!err) { + int jerror; + mutex_lock_nested(&dir->d_parent->d_inode->i_mutex, + I_MUTEX_XATTR); + err = action(dir, data); + jerror = journal_end(&th, inode->i_sb, blocks); + mutex_unlock(&dir->d_parent->d_inode->i_mutex); + err = jerror ?: err; + } } - - dput(root); +out_dir: + dput(dir); out: - if (err) - reiserfs_warning(inode->i_sb, "jdm-20004", - "Couldn't remove all xattrs (%d)\n", err); + /* -ENODATA isn't an error */ + if (err == -ENODATA) + err = 0; return err; } -struct reiserfs_chown_buf { - struct inode *inode; - struct dentry *xadir; - struct iattr *attrs; -}; - -/* XXX: If there is a better way to do this, I'd love to hear about it */ -static int -reiserfs_chown_xattrs_filler(void *buf, const char *name, int namelen, - loff_t offset, u64 ino, unsigned int d_type) +static int delete_one_xattr(struct dentry *dentry, void *data) { - struct reiserfs_chown_buf *chown_buf = (struct reiserfs_chown_buf *)buf; - struct dentry *xafile, *xadir = chown_buf->xadir; - struct iattr *attrs = chown_buf->attrs; - int err = 0; + struct inode *dir = dentry->d_parent->d_inode; - xafile = lookup_one_len(name, xadir, namelen); - if (IS_ERR(xafile)) - return PTR_ERR(xafile); - else if (!xafile->d_inode) { - dput(xafile); - return -ENODATA; - } + /* This is the xattr dir, handle specially. */ + if (S_ISDIR(dentry->d_inode->i_mode)) + return xattr_rmdir(dir, dentry); - if (!S_ISDIR(xafile->d_inode->i_mode)) { - mutex_lock_nested(&xafile->d_inode->i_mutex, I_MUTEX_CHILD); - err = reiserfs_setattr(xafile, attrs); - mutex_unlock(&xafile->d_inode->i_mutex); - } - dput(xafile); + return xattr_unlink(dir, dentry); +} + +static int chown_one_xattr(struct dentry *dentry, void *data) +{ + struct iattr *attrs = data; + return reiserfs_setattr(dentry, attrs); +} +/* No i_mutex, but the inode is unconnected. */ +int reiserfs_delete_xattrs(struct inode *inode) +{ + int err = reiserfs_for_each_xattr(inode, delete_one_xattr, NULL); + if (err) + reiserfs_warning(inode->i_sb, "jdm-20004", + "Couldn't delete all xattrs (%d)\n", err); return err; } +/* inode->i_mutex: down */ int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs) { - struct dentry *dir; - int err = 0; - struct reiserfs_chown_buf buf; - unsigned int ia_valid = attrs->ia_valid; - - /* Skip out, an xattr has no xattrs associated with it */ - if (IS_PRIVATE(inode) || get_inode_sd_version(inode) == STAT_DATA_V1) - return 0; - - dir = open_xa_dir(inode, XATTR_REPLACE); - if (IS_ERR(dir)) { - if (PTR_ERR(dir) != -ENODATA) - err = PTR_ERR(dir); - goto out; - } else if (!dir->d_inode) - goto out_dir; - - attrs->ia_valid &= (ATTR_UID | ATTR_GID | ATTR_CTIME); - buf.xadir = dir; - buf.attrs = attrs; - buf.inode = inode; - - mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_XATTR); - err = xattr_readdir(dir->d_inode, reiserfs_chown_xattrs_filler, &buf); - - if (!err) - err = reiserfs_setattr(dir, attrs); - mutex_unlock(&dir->d_inode->i_mutex); - - attrs->ia_valid = ia_valid; -out_dir: - dput(dir); -out: + int err = reiserfs_for_each_xattr(inode, chown_one_xattr, attrs); if (err) reiserfs_warning(inode->i_sb, "jdm-20007", "Couldn't chown all xattrs (%d)\n", err); @@ -1004,6 +831,7 @@ ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size) { struct dentry *dir; int err = 0; + loff_t pos = 0; struct listxattr_buf buf = { .inode = dentry->d_inode, .buf = buffer, @@ -1026,7 +854,7 @@ ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size) } mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_XATTR); - err = xattr_readdir(dir->d_inode, listxattr_filler, &buf); + err = reiserfs_readdir_dentry(dir, &buf, listxattr_filler, &pos); mutex_unlock(&dir->d_inode->i_mutex); if (!err) diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h index 67ad310fa88b..c0365e07fce6 100644 --- a/include/linux/reiserfs_fs.h +++ b/include/linux/reiserfs_fs.h @@ -1984,6 +1984,7 @@ extern const struct inode_operations reiserfs_dir_inode_operations; extern const struct inode_operations reiserfs_symlink_inode_operations; extern const struct inode_operations reiserfs_special_inode_operations; extern const struct file_operations reiserfs_dir_operations; +int reiserfs_readdir_dentry(struct dentry *, void *, filldir_t, loff_t *); /* tail_conversion.c */ int direct2indirect(struct reiserfs_transaction_handle *, struct inode *, -- cgit v1.2.3