Hello,

  attached patch makes ext3 use bit operations to manipulate its
EXT3_I->i_flags. So far i_flags modifications were usually guarded
by i_mutex but my next patch needs to modify i_flags without i_mutex.
  BTW: Is there any type + functions, which allow both bit operations
and things like atomic_read() and atomic_set()? It would be nice to
use them here - currently I just assign to the variable but I'm not sure if
this cannot result in some garbage on some strange architecture.

                                                                Honza

-- 
Jan Kara <[EMAIL PROTECTED]>
SUSE Labs, CR

Use set_bit(), clear_bit() and test_bit() to manipulate EXT3_I->i_flags.
This allows concurrent updates to EXT3_I->i_flags. At several places
we need to copy EXT3_I->i_flags as a whole - we do it non-atomically
and hope we don't get any garbage.

Signed-off-by: Jan Kara <[EMAIL PROTECTED]>

diff -rupX /home/jack/.kerndiffexclude linux-2.6.23/fs/ext3/dir.c 
linux-2.6.23-1-ext3_iflags_locking/fs/ext3/dir.c
--- linux-2.6.23/fs/ext3/dir.c  2007-10-11 12:01:23.000000000 +0200
+++ linux-2.6.23-1-ext3_iflags_locking/fs/ext3/dir.c    2007-10-11 
18:03:19.000000000 +0200
@@ -110,7 +110,7 @@ static int ext3_readdir(struct file * fi
 #ifdef CONFIG_EXT3_INDEX
        if (EXT3_HAS_COMPAT_FEATURE(inode->i_sb,
                                    EXT3_FEATURE_COMPAT_DIR_INDEX) &&
-           ((EXT3_I(inode)->i_flags & EXT3_INDEX_FL) ||
+           (test_bit(EXT3_INDEX_FL, &EXT3_I(inode)->i_flags) ||
             ((inode->i_size >> sb->s_blocksize_bits) == 1))) {
                err = ext3_dx_readdir(filp, dirent, filldir);
                if (err != ERR_BAD_DX_DIR) {
@@ -121,7 +121,7 @@ static int ext3_readdir(struct file * fi
                 * We don't set the inode dirty flag since it's not
                 * critical that it get flushed back to the disk.
                 */
-               EXT3_I(filp->f_path.dentry->d_inode)->i_flags &= ~EXT3_INDEX_FL;
+               clear_bit(EXT3_INDEX_FL, 
&EXT3_I(filp->f_path.dentry->d_inode)->i_flags);
        }
 #endif
        stored = 0;
diff -rupX /home/jack/.kerndiffexclude linux-2.6.23/fs/ext3/ialloc.c 
linux-2.6.23-1-ext3_iflags_locking/fs/ext3/ialloc.c
--- linux-2.6.23/fs/ext3/ialloc.c       2006-11-29 22:57:37.000000000 +0100
+++ linux-2.6.23-1-ext3_iflags_locking/fs/ext3/ialloc.c 2007-10-11 
18:05:48.000000000 +0200
@@ -278,7 +278,7 @@ static int find_group_orlov(struct super
        ndirs = percpu_counter_read_positive(&sbi->s_dirs_counter);
 
        if ((parent == sb->s_root->d_inode) ||
-           (EXT3_I(parent)->i_flags & EXT3_TOPDIR_FL)) {
+           test_bit(EXT3_TOPDIR_FL, &EXT3_I(parent)->i_flags)) {
                int best_ndir = inodes_per_group;
                int best_group = -1;
 
diff -rupX /home/jack/.kerndiffexclude linux-2.6.23/fs/ext3/inode.c 
linux-2.6.23-1-ext3_iflags_locking/fs/ext3/inode.c
--- linux-2.6.23/fs/ext3/inode.c        2007-10-11 12:01:23.000000000 +0200
+++ linux-2.6.23-1-ext3_iflags_locking/fs/ext3/inode.c  2007-10-11 
18:13:04.000000000 +0200
@@ -2557,18 +2557,16 @@ int ext3_get_inode_loc(struct inode *ino
 
 void ext3_set_inode_flags(struct inode *inode)
 {
-       unsigned int flags = EXT3_I(inode)->i_flags;
-
        inode->i_flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC);
-       if (flags & EXT3_SYNC_FL)
+       if (test_bit(EXT3_SYNC_FL, &EXT3_I(inode)->i_flags))
                inode->i_flags |= S_SYNC;
-       if (flags & EXT3_APPEND_FL)
+       if (test_bit(EXT3_APPEND_FL, &EXT3_I(inode)->i_flags))
                inode->i_flags |= S_APPEND;
-       if (flags & EXT3_IMMUTABLE_FL)
+       if (test_bit(EXT3_IMMUTABLE_FL, &EXT3_I(inode)->i_flags))
                inode->i_flags |= S_IMMUTABLE;
-       if (flags & EXT3_NOATIME_FL)
+       if (test_bit(EXT3_NOATIME_FL, &EXT3_I(inode)->i_flags))
                inode->i_flags |= S_NOATIME;
-       if (flags & EXT3_DIRSYNC_FL)
+       if (test_bit(EXT3_DIRSYNC_FL, &EXT3_I(inode)->i_flags))
                inode->i_flags |= S_DIRSYNC;
 }
 
@@ -2577,18 +2575,26 @@ void ext3_get_inode_flags(struct ext3_in
 {
        unsigned int flags = ei->vfs_inode.i_flags;
 
-       ei->i_flags &= ~(EXT3_SYNC_FL|EXT3_APPEND_FL|
-                       EXT3_IMMUTABLE_FL|EXT3_NOATIME_FL|EXT3_DIRSYNC_FL);
        if (flags & S_SYNC)
-               ei->i_flags |= EXT3_SYNC_FL;
+               set_bit(EXT3_SYNC_FL, &ei->i_flags);
+       else
+               clear_bit(EXT3_SYNC_FL, &ei->i_flags);
        if (flags & S_APPEND)
-               ei->i_flags |= EXT3_APPEND_FL;
+               set_bit(EXT3_APPEND_FL, &ei->i_flags);
+       else
+               clear_bit(EXT3_APPEND_FL, &ei->i_flags);
        if (flags & S_IMMUTABLE)
-               ei->i_flags |= EXT3_IMMUTABLE_FL;
+               set_bit(EXT3_IMMUTABLE_FL, &ei->i_flags);
+       else
+               clear_bit(EXT3_IMMUTABLE_FL, &ei->i_flags);
        if (flags & S_NOATIME)
-               ei->i_flags |= EXT3_NOATIME_FL;
+               set_bit(EXT3_NOATIME_FL, &ei->i_flags);
+       else
+               clear_bit(EXT3_NOATIME_FL, &ei->i_flags);
        if (flags & S_DIRSYNC)
-               ei->i_flags |= EXT3_DIRSYNC_FL;
+               set_bit(EXT3_DIRSYNC_FL, &ei->i_flags);
+       else
+               clear_bit(EXT3_DIRSYNC_FL, &ei->i_flags);
 }
 
 void ext3_read_inode(struct inode * inode)
@@ -3210,9 +3216,9 @@ int ext3_change_inode_journal_flag(struc
         */
 
        if (val)
-               EXT3_I(inode)->i_flags |= EXT3_JOURNAL_DATA_FL;
+               set_bit(EXT3_JOURNAL_DATA_FL, &EXT3_I(inode)->i_flags);
        else
-               EXT3_I(inode)->i_flags &= ~EXT3_JOURNAL_DATA_FL;
+               clear_bit(EXT3_JOURNAL_DATA_FL, &EXT3_I(inode)->i_flags);
        ext3_set_aops(inode);
 
        journal_unlock_updates(journal);
diff -rupX /home/jack/.kerndiffexclude linux-2.6.23/fs/ext3/namei.c 
linux-2.6.23-1-ext3_iflags_locking/fs/ext3/namei.c
--- linux-2.6.23/fs/ext3/namei.c        2007-10-11 12:01:23.000000000 +0200
+++ linux-2.6.23-1-ext3_iflags_locking/fs/ext3/namei.c  2007-10-11 
18:09:11.000000000 +0200
@@ -629,7 +629,7 @@ int ext3_htree_fill_tree(struct file *di
        dxtrace(printk("In htree_fill_tree, start hash: %x:%x\n", start_hash,
                       start_minor_hash));
        dir = dir_file->f_path.dentry->d_inode;
-       if (!(EXT3_I(dir)->i_flags & EXT3_INDEX_FL)) {
+       if (!test_bit(EXT3_INDEX_FL, &EXT3_I(dir)->i_flags)) {
                hinfo.hash_version = EXT3_SB(dir->i_sb)->s_def_hash_version;
                hinfo.seed = EXT3_SB(dir->i_sb)->s_hash_seed;
                count = htree_dirblock_to_tree(dir_file, dir, 0, &hinfo,
@@ -775,7 +775,7 @@ static void ext3_update_dx_flag(struct i
 {
        if (!EXT3_HAS_COMPAT_FEATURE(inode->i_sb,
                                     EXT3_FEATURE_COMPAT_DIR_INDEX))
-               EXT3_I(inode)->i_flags &= ~EXT3_INDEX_FL;
+               clear_bit(&EXT3_I(inode)->i_flags, EXT3_INDEX_FL);
 }
 
 /*
@@ -1405,7 +1405,7 @@ static int make_indexed_dir(handle_t *ha
                brelse(bh);
                return retval;
        }
-       EXT3_I(dir)->i_flags |= EXT3_INDEX_FL;
+       set_bit(&EXT3_I(dir)->i_flags, EXT3_INDEX_FL);
        data1 = bh2->b_data;
 
        /* The 0th block becomes the root, move the dirents out */
@@ -1481,7 +1481,7 @@ static int ext3_add_entry (handle_t *han
                retval = ext3_dx_add_entry(handle, dentry, inode);
                if (!retval || (retval != ERR_BAD_DX_DIR))
                        return retval;
-               EXT3_I(dir)->i_flags &= ~EXT3_INDEX_FL;
+               clear_bit(EXT3_INDEX_FL, &EXT3_I(dir)->i_flags);
                dx_fallback++;
                ext3_mark_inode_dirty(handle, dir);
        }
diff -rupX /home/jack/.kerndiffexclude linux-2.6.23/include/linux/ext3_fs.h 
linux-2.6.23-1-ext3_iflags_locking/include/linux/ext3_fs.h
--- linux-2.6.23/include/linux/ext3_fs.h        2007-07-16 17:47:28.000000000 
+0200
+++ linux-2.6.23-1-ext3_iflags_locking/include/linux/ext3_fs.h  2007-10-11 
17:01:28.000000000 +0200
@@ -157,27 +157,27 @@ struct ext3_group_desc
 /*
  * Inode flags
  */
-#define        EXT3_SECRM_FL                   0x00000001 /* Secure deletion */
-#define        EXT3_UNRM_FL                    0x00000002 /* Undelete */
-#define        EXT3_COMPR_FL                   0x00000004 /* Compress file */
-#define EXT3_SYNC_FL                   0x00000008 /* Synchronous updates */
-#define EXT3_IMMUTABLE_FL              0x00000010 /* Immutable file */
-#define EXT3_APPEND_FL                 0x00000020 /* writes to file may only 
append */
-#define EXT3_NODUMP_FL                 0x00000040 /* do not dump file */
-#define EXT3_NOATIME_FL                        0x00000080 /* do not update 
atime */
+#define        EXT3_SECRM_FL                    0 /* Secure deletion */
+#define        EXT3_UNRM_FL                     1 /* Undelete */
+#define        EXT3_COMPR_FL                    2 /* Compress file */
+#define EXT3_SYNC_FL                    3 /* Synchronous updates */
+#define EXT3_IMMUTABLE_FL               4 /* Immutable file */
+#define EXT3_APPEND_FL                  5 /* writes to file may only append */
+#define EXT3_NODUMP_FL                  6 /* do not dump file */
+#define EXT3_NOATIME_FL                         7 /* do not update atime */
 /* Reserved for compression usage... */
-#define EXT3_DIRTY_FL                  0x00000100
-#define EXT3_COMPRBLK_FL               0x00000200 /* One or more compressed 
clusters */
-#define EXT3_NOCOMPR_FL                        0x00000400 /* Don't compress */
-#define EXT3_ECOMPR_FL                 0x00000800 /* Compression error */
+#define EXT3_DIRTY_FL                   8
+#define EXT3_COMPRBLK_FL                9 /* One or more compressed clusters */
+#define EXT3_NOCOMPR_FL                        10 /* Don't compress */
+#define EXT3_ECOMPR_FL                 11 /* Compression error */
 /* End compression flags --- maybe not all used */
-#define EXT3_INDEX_FL                  0x00001000 /* hash-indexed directory */
-#define EXT3_IMAGIC_FL                 0x00002000 /* AFS directory */
-#define EXT3_JOURNAL_DATA_FL           0x00004000 /* file data should be 
journaled */
-#define EXT3_NOTAIL_FL                 0x00008000 /* file tail should not be 
merged */
-#define EXT3_DIRSYNC_FL                        0x00010000 /* dirsync behaviour 
(directories only) */
-#define EXT3_TOPDIR_FL                 0x00020000 /* Top of directory 
hierarchies*/
-#define EXT3_RESERVED_FL               0x80000000 /* reserved for ext3 lib */
+#define EXT3_INDEX_FL                  12 /* hash-indexed directory */
+#define EXT3_IMAGIC_FL                 13 /* AFS directory */
+#define EXT3_JOURNAL_DATA_FL           14 /* file data should be journaled */
+#define EXT3_NOTAIL_FL                 15 /* file tail should not be merged */
+#define EXT3_DIRSYNC_FL                        16 /* dirsync behaviour 
(directories only) */
+#define EXT3_TOPDIR_FL                 17 /* Top of directory hierarchies*/
+#define EXT3_RESERVED_FL               31 /* reserved for ext3 lib */
 
 #define EXT3_FL_USER_VISIBLE           0x0003DFFF /* User visible flags */
 #define EXT3_FL_USER_MODIFIABLE                0x000380FF /* User modifiable 
flags */
-
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to