[PATCH COW] lock_flags

From: Jörn Engel
Date: Thu May 06 2004 - 08:39:05 EST


Patch 4 - just for completeness

Jörn

--
Optimizations always bust things, because all optimizations are, in
the long haul, a form of cheating, and cheaters eventually get caught.
-- Larry Wall

spins on i_lock before accessing i_flags

Omissions:
o fs/befs/linuxvfs.c inode->i_flags should be befs_ino->i_flags
o fs/dquot.c vfs_quota_on() is racy. the race is now limited to
S_NOATIME, S_QUOTA and S_NOQUOTA, but it still exists.

drivers/usb/core/inode.c | 2 ++
fs/afs/inode.c | 2 ++
fs/dquot.c | 21 ++++++++++++++++++---
fs/ext2/ialloc.c | 2 ++
fs/ext2/inode.c | 2 ++
fs/ext3/ialloc.c | 2 ++
fs/ext3/inode.c | 2 ++
fs/fat/inode.c | 5 ++++-
fs/hfs/inode.c | 2 +-
fs/hfsplus/catalog.c | 4 ++--
fs/hfsplus/dir.c | 10 ++++++++--
fs/hfsplus/inode.c | 6 +++++-
fs/hfsplus/ioctl.c | 2 ++
fs/intermezzo/vfs.c | 7 ++++++-
fs/namei.c | 10 ++++++++--
fs/nfs/inode.c | 2 ++
fs/proc/base.c | 4 ++++
fs/reiserfs/inode.c | 9 ++++++++-
fs/smbfs/file.c | 2 +-
fs/udf/ialloc.c | 2 ++
fs/ufs/ialloc.c | 2 ++
fs/xfs/linux/xfs_ioctl.c | 2 +-
fs/xfs/linux/xfs_super.c | 2 ++
fs/xfs/linux/xfs_vnode.c | 2 ++
fs/xfs/xfs_acl.c | 2 +-
fs/xfs/xfs_cap.c | 2 +-
include/linux/fs.h | 32 +++++++++++++++++++++-----------
27 files changed, 113 insertions(+), 29 deletions(-)


--- linux-2.6.5cow/include/linux/fs.h~lock_flags 2004-04-14 16:22:15.000000000 +0200
+++ linux-2.6.5cow/include/linux/fs.h 2004-04-27 16:34:42.000000000 +0200
@@ -155,24 +155,25 @@
*/
#define __IS_FLG(inode,flg) ((inode)->i_sb->s_flags & (flg))

-#define IS_RDONLY(inode) ((inode)->i_sb->s_flags & MS_RDONLY)
+#define IS_RDONLY(inode) (__IS_FLG(inode, MS_RDONLY))
#define IS_SYNC(inode) (__IS_FLG(inode, MS_SYNCHRONOUS) || \
- ((inode)->i_flags & S_SYNC))
+ inode_flags((inode), S_SYNC))
#define IS_DIRSYNC(inode) (__IS_FLG(inode, MS_SYNCHRONOUS|MS_DIRSYNC) || \
- ((inode)->i_flags & (S_SYNC|S_DIRSYNC)))
+ inode_flags((inode), (S_SYNC|S_DIRSYNC)))
#define IS_MANDLOCK(inode) __IS_FLG(inode, MS_MANDLOCK)

-#define IS_QUOTAINIT(inode) ((inode)->i_flags & S_QUOTA)
-#define IS_NOQUOTA(inode) ((inode)->i_flags & S_NOQUOTA)
-#define IS_APPEND(inode) ((inode)->i_flags & S_APPEND)
-#define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE)
-#define IS_NOATIME(inode) (__IS_FLG(inode, MS_NOATIME) || ((inode)->i_flags & S_NOATIME))
+#define IS_QUOTAINIT(inode) (inode_flags((inode), S_QUOTA))
+#define IS_NOQUOTA(inode) (inode_flags((inode), S_NOQUOTA))
+#define IS_APPEND(inode) (inode_flags((inode), S_APPEND))
+#define IS_IMMUTABLE(inode) (inode_flags((inode), S_IMMUTABLE))
+#define IS_NOATIME(inode) (__IS_FLG(inode, MS_NOATIME) || \
+ inode_flags((inode), S_NOATIME))
#define IS_NODIRATIME(inode) __IS_FLG(inode, MS_NODIRATIME)
#define IS_POSIXACL(inode) __IS_FLG(inode, MS_POSIXACL)
#define IS_ONE_SECOND(inode) __IS_FLG(inode, MS_ONE_SECOND)

-#define IS_DEADDIR(inode) ((inode)->i_flags & S_DEAD)
-#define IS_NOCMTIME(inode) ((inode)->i_flags & S_NOCMTIME)
+#define IS_DEADDIR(inode) (inode_flags((inode), S_DEAD))
+#define IS_NOCMTIME(inode) (inode_flags((inode), S_NOCMTIME))

/* the read-only stuff doesn't really belong here, but any other place is
probably as bad and I don't want to create yet another include file. */
@@ -417,7 +418,7 @@
unsigned long i_state;
unsigned long dirtied_when; /* jiffies of first dirtying */

- unsigned int i_flags;
+ unsigned int i_flags; /* protected by i_lock */
unsigned char i_sock;

atomic_t i_writecount;
@@ -431,6 +432,15 @@
#endif
};

+static inline unsigned int inode_flags(struct inode *inode, unsigned int mask)
+{
+ int ret;
+ spin_lock(inode->i_lock);
+ ret = inode->i_flags & mask;
+ spin_unlock(inode->i_lock);
+ return ret;
+}
+
/*
* NOTE: in a 32bit arch with a preemptable kernel and
* an UP compile the i_size_read/write must be atomic
--- linux-2.6.5cow/drivers/usb/core/inode.c~lock_flags 2004-04-14 16:22:15.000000000 +0200
+++ linux-2.6.5cow/drivers/usb/core/inode.c 2004-04-14 16:22:24.000000000 +0200
@@ -277,7 +277,9 @@
if (usbfs_empty(dentry)) {
dentry->d_inode->i_nlink -= 2;
dput(dentry);
+ spin_lock(inode->i_lock);
inode->i_flags |= S_DEAD;
+ spin_unlock(inode->i_lock);
dir->i_nlink--;
error = 0;
}
--- linux-2.6.5cow/fs/xfs/linux/xfs_vnode.c~lock_flags 2004-04-14 16:22:15.000000000 +0200
+++ linux-2.6.5cow/fs/xfs/linux/xfs_vnode.c 2004-04-14 16:22:24.000000000 +0200
@@ -213,6 +213,7 @@
inode->i_mtime = va.va_mtime;
inode->i_ctime = va.va_ctime;
inode->i_atime = va.va_atime;
+ spin_lock(inode->i_lock);
if (va.va_xflags & XFS_XFLAG_IMMUTABLE)
inode->i_flags |= S_IMMUTABLE;
else
@@ -229,6 +230,7 @@
inode->i_flags |= S_NOATIME;
else
inode->i_flags &= ~S_NOATIME;
+ spin_unlock(inode->i_lock);
VUNMODIFY(vp);
}
return -error;
--- linux-2.6.5cow/fs/xfs/linux/xfs_ioctl.c~lock_flags 2004-04-14 16:22:15.000000000 +0200
+++ linux-2.6.5cow/fs/xfs/linux/xfs_ioctl.c 2004-04-14 16:22:24.000000000 +0200
@@ -885,7 +885,7 @@
int attr_flags = 0;
int error;

- if (vp->v_inode.i_flags & (S_IMMUTABLE|S_APPEND))
+ if (inode_flags(vp->v_inode, (S_IMMUTABLE|S_APPEND)))
return -XFS_ERROR(EPERM);

if (!(filp->f_flags & FMODE_WRITE))
--- linux-2.6.5cow/fs/xfs/linux/xfs_super.c~lock_flags 2004-04-14 16:22:15.000000000 +0200
+++ linux-2.6.5cow/fs/xfs/linux/xfs_super.c 2004-04-14 16:22:24.000000000 +0200
@@ -187,6 +187,7 @@
inode->i_mtime.tv_nsec = ip->i_d.di_mtime.t_nsec;
inode->i_ctime.tv_sec = ip->i_d.di_ctime.t_sec;
inode->i_ctime.tv_nsec = ip->i_d.di_ctime.t_nsec;
+ spin_lock(inode->i_lock);
if (ip->i_d.di_flags & XFS_DIFLAG_IMMUTABLE)
inode->i_flags |= S_IMMUTABLE;
else
@@ -203,6 +204,7 @@
inode->i_flags |= S_NOATIME;
else
inode->i_flags &= ~S_NOATIME;
+ spin_unlock(inode->i_lock);
vp->v_flag &= ~VMODIFIED;
}

--- linux-2.6.5cow/fs/xfs/xfs_acl.c~lock_flags 2004-04-14 16:22:15.000000000 +0200
+++ linux-2.6.5cow/fs/xfs/xfs_acl.c 2004-04-14 16:22:24.000000000 +0200
@@ -388,7 +388,7 @@
vattr_t va;
int error;

- if (vp->v_inode.i_flags & (S_IMMUTABLE|S_APPEND))
+ if (inode_flags(&vp->v_inode, (S_IMMUTABLE|S_APPEND)))
return EPERM;
if (kind == _ACL_TYPE_DEFAULT && vp->v_type != VDIR)
return ENOTDIR;
--- linux-2.6.5cow/fs/xfs/xfs_cap.c~lock_flags 2004-04-14 16:22:15.000000000 +0200
+++ linux-2.6.5cow/fs/xfs/xfs_cap.c 2004-04-14 16:22:24.000000000 +0200
@@ -192,7 +192,7 @@

if (vp->v_vfsp->vfs_flag & VFS_RDONLY)
return EROFS;
- if (vp->v_inode.i_flags & (S_IMMUTABLE|S_APPEND))
+ if (inode_flags(&vp->v_inode, (S_IMMUTABLE|S_APPEND)))
return EPERM;
if ((error = _MAC_VACCESS(vp, NULL, VWRITE)))
return error;
--- linux-2.6.5cow/fs/nfs/inode.c~lock_flags 2004-04-14 16:22:15.000000000 +0200
+++ linux-2.6.5cow/fs/nfs/inode.c 2004-04-14 16:22:24.000000000 +0200
@@ -695,7 +695,9 @@
inode->i_ino = hash;

/* We can't support update_atime(), since the server will reset it */
+ spin_lock(inode->i_lock);
inode->i_flags |= S_NOATIME|S_NOCMTIME;
+ spin_unlock(inode->i_lock);
inode->i_mode = fattr->mode;
/* Why so? Because we want revalidate for devices/FIFOs, and
* that's precisely what we have in nfs_file_inode_operations.
--- linux-2.6.5cow/fs/ufs/ialloc.c~lock_flags 2004-04-14 16:22:15.000000000 +0200
+++ linux-2.6.5cow/fs/ufs/ialloc.c 2004-04-14 16:22:24.000000000 +0200
@@ -283,7 +283,9 @@

if (DQUOT_ALLOC_INODE(inode)) {
DQUOT_DROP(inode);
+ spin_lock(inode->i_lock);
inode->i_flags |= S_NOQUOTA;
+ spin_unlock(inode->i_lock);
inode->i_nlink = 0;
iput(inode);
return ERR_PTR(-EDQUOT);
--- linux-2.6.5cow/fs/hfs/inode.c~lock_flags 2004-04-14 16:22:15.000000000 +0200
+++ linux-2.6.5cow/fs/hfs/inode.c 2004-04-20 16:20:21.000000000 +0200
@@ -540,7 +540,7 @@
if (atomic_dec_and_test(&HFS_I(inode)->opencnt)) {
down(&inode->i_sem);
hfs_file_truncate(inode);
- //if (inode->i_flags & S_DEAD) {
+ //if (IS_DEADDIR(inode) {
// hfs_delete_cat(inode->i_ino, HFSPLUS_SB(sb).hidden_dir, NULL);
// hfs_delete_inode(inode);
//}
--- linux-2.6.5cow/fs/intermezzo/vfs.c~lock_flags 2004-04-14 16:22:15.000000000 +0200
+++ linux-2.6.5cow/fs/intermezzo/vfs.c 2004-04-14 16:22:24.000000000 +0200
@@ -1441,7 +1441,9 @@
error = iops->rmdir(dir->d_inode, dentry);
unlock_kernel();
if (!error) {
+ spin_lock(dentry->d_inode->i_lock);
dentry->d_inode->i_flags |= S_DEAD;
+ spin_unlock(dentry->d_inode->i_lock);
error = presto_settime(fset, NULL, NULL, dir, info,
ATTR_CTIME | ATTR_MTIME);
}
@@ -1838,8 +1840,11 @@
error = do_rename(fset, old_parent, old_dentry,
new_parent, new_dentry, info);
if (target) {
- if (!error)
+ if (!error) {
+ spin_lock(target);
target->i_flags |= S_DEAD;
+ spin_unlock(target);
+ }
// triple_up(&old_dir->i_zombie,
// &new_dir->i_zombie,
// &target->i_zombie);
--- linux-2.6.5cow/fs/udf/ialloc.c~lock_flags 2004-04-14 16:22:15.000000000 +0200
+++ linux-2.6.5cow/fs/udf/ialloc.c 2004-04-14 16:22:24.000000000 +0200
@@ -165,7 +165,9 @@
if (DQUOT_ALLOC_INODE(inode))
{
DQUOT_DROP(inode);
+ spin_lock(inode->i_lock);
inode->i_flags |= S_NOQUOTA;
+ spin_unlock(inode->i_lock);
inode->i_nlink = 0;
iput(inode);
*err = -EDQUOT;
--- linux-2.6.5cow/fs/reiserfs/inode.c~lock_flags 2004-04-14 16:22:15.000000000 +0200
+++ linux-2.6.5cow/fs/reiserfs/inode.c 2004-04-20 16:20:21.000000000 +0200
@@ -1612,8 +1612,11 @@
/* uid and gid must already be set by the caller for quota init */

/* symlink cannot be immutable or append only, right? */
- if( S_ISLNK( inode -> i_mode ) )
+ if( S_ISLNK( inode -> i_mode ) ) {
+ spin_lock(inode->i_lock);
inode -> i_flags &= ~ ( S_IMMUTABLE | S_APPEND );
+ spin_unlock(inode->i_lock);
+ }

inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
inode->i_size = i_size;
@@ -2287,6 +2290,7 @@
void sd_attrs_to_i_attrs( __u16 sd_attrs, struct inode *inode )
{
if( reiserfs_attrs( inode -> i_sb ) ) {
+ spin_lock(inode->i_lock);
if( sd_attrs & REISERFS_SYNC_FL )
inode -> i_flags |= S_SYNC;
else
@@ -2307,12 +2311,14 @@
REISERFS_I(inode)->i_flags |= i_nopack_mask;
else
REISERFS_I(inode)->i_flags &= ~i_nopack_mask;
+ spin_unlock(inode->i_lock);
}
}

void i_attrs_to_sd_attrs( struct inode *inode, __u16 *sd_attrs )
{
if( reiserfs_attrs( inode -> i_sb ) ) {
+ spin_lock(inode->i_lock);
if( inode -> i_flags & S_IMMUTABLE )
*sd_attrs |= REISERFS_IMMUTABLE_FL;
else
@@ -2329,6 +2335,7 @@
*sd_attrs |= REISERFS_NOTAIL_FL;
else
*sd_attrs &= ~REISERFS_NOTAIL_FL;
+ spin_unlock(inode->i_lock);
}
}

--- linux-2.6.5cow/fs/fat/inode.c~lock_flags 2004-04-14 16:22:15.000000000 +0200
+++ linux-2.6.5cow/fs/fat/inode.c 2004-04-20 16:20:21.000000000 +0200
@@ -1193,8 +1193,11 @@
MSDOS_I(inode)->mmu_private = inode->i_size;
}
if(de->attr & ATTR_SYS)
- if (sbi->options.sys_immutable)
+ if (sbi->options.sys_immutable) {
+ spin_lock(inode->i_lock);
inode->i_flags |= S_IMMUTABLE;
+ spin_unlock(inode->i_lock);
+ }
MSDOS_I(inode)->i_attrs = de->attr & ATTR_UNUSED;
/* this is as close to the truth as we can get ... */
inode->i_blksize = sbi->cluster_size;
--- linux-2.6.5cow/fs/ext3/ialloc.c~lock_flags 2004-04-14 16:22:15.000000000 +0200
+++ linux-2.6.5cow/fs/ext3/ialloc.c 2004-04-14 16:22:24.000000000 +0200
@@ -627,7 +627,9 @@
return ret;

fail2:
+ spin_lock(inode->i_lock);
inode->i_flags |= S_NOQUOTA;
+ spin_unlock(inode->i_lock);
inode->i_nlink = 0;
iput(inode);
brelse(bitmap_bh);
--- linux-2.6.5cow/fs/ext3/inode.c~lock_flags 2004-04-14 16:22:15.000000000 +0200
+++ linux-2.6.5cow/fs/ext3/inode.c 2004-04-27 16:34:42.000000000 +0200
@@ -2447,6 +2447,7 @@
{
unsigned int flags = EXT3_I(inode)->i_flags;

+ spin_lock(inode->i_lock);
inode->i_flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC);
if (flags & EXT3_SYNC_FL)
inode->i_flags |= S_SYNC;
@@ -2458,6 +2459,7 @@
inode->i_flags |= S_NOATIME;
if (flags & EXT3_DIRSYNC_FL)
inode->i_flags |= S_DIRSYNC;
+ spin_unlock(inode->i_lock);
}

void ext3_read_inode(struct inode * inode)
--- linux-2.6.5cow/fs/proc/base.c~lock_flags 2004-04-14 16:22:15.000000000 +0200
+++ linux-2.6.5cow/fs/proc/base.c 2004-04-14 16:22:24.000000000 +0200
@@ -1594,7 +1594,9 @@
inode->i_op = &proc_tgid_base_inode_operations;
inode->i_fop = &proc_tgid_base_operations;
inode->i_nlink = 3;
+ spin_lock(inode->i_lock);
inode->i_flags|=S_IMMUTABLE;
+ spin_unlock(inode->i_lock);

dentry->d_op = &pid_base_dentry_operations;

@@ -1649,7 +1651,9 @@
inode->i_op = &proc_tid_base_inode_operations;
inode->i_fop = &proc_tid_base_operations;
inode->i_nlink = 3;
+ spin_lock(inode->i_lock);
inode->i_flags|=S_IMMUTABLE;
+ spin_unlock(inode->i_lock);

dentry->d_op = &pid_base_dentry_operations;

--- linux-2.6.5cow/fs/ext2/inode.c~lock_flags 2004-04-14 16:22:15.000000000 +0200
+++ linux-2.6.5cow/fs/ext2/inode.c 2004-04-27 16:34:42.000000000 +0200
@@ -1020,6 +1020,7 @@
{
unsigned int flags = EXT2_I(inode)->i_flags;

+ spin_lock(inode->i_lock);
inode->i_flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC);
if (flags & EXT2_SYNC_FL)
inode->i_flags |= S_SYNC;
@@ -1031,6 +1032,7 @@
inode->i_flags |= S_NOATIME;
if (flags & EXT2_DIRSYNC_FL)
inode->i_flags |= S_DIRSYNC;
+ spin_unlock(inode->i_lock);
}

void ext2_read_inode (struct inode * inode)
--- linux-2.6.5cow/fs/ext2/ialloc.c~lock_flags 2004-04-14 16:22:15.000000000 +0200
+++ linux-2.6.5cow/fs/ext2/ialloc.c 2004-04-14 16:22:24.000000000 +0200
@@ -620,7 +620,9 @@
return inode;

fail2:
+ spin_lock(inode->i_lock);
inode->i_flags |= S_NOQUOTA;
+ spin_unlock(inode->i_lock);
inode->i_nlink = 0;
iput(inode);
return ERR_PTR(err);
--- linux-2.6.5cow/fs/namei.c~lock_flags 2004-04-14 16:22:15.000000000 +0200
+++ linux-2.6.5cow/fs/namei.c 2004-04-27 16:34:42.000000000 +0200
@@ -1609,8 +1609,11 @@
error = security_inode_rmdir(dir, dentry);
if (!error) {
error = dir->i_op->rmdir(dir, dentry);
- if (!error)
+ if (!error) {
+ spin_lock(dentry->d_inode->i_lock);
dentry->d_inode->i_flags |= S_DEAD;
+ spin_unlock(dentry->d_inode->i_lock);
+ }
}
}
up(&dentry->d_inode->i_sem);
@@ -1952,8 +1955,11 @@
else
error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
if (target) {
- if (!error)
+ if (!error) {
+ spin_lock(target->i_lock);
target->i_flags |= S_DEAD;
+ spin_unlock(target->i_lock);
+ }
up(&target->i_sem);
if (d_unhashed(new_dentry))
d_rehash(new_dentry);
--- linux-2.6.5cow/fs/dquot.c~lock_flags 2004-04-14 16:22:15.000000000 +0200
+++ linux-2.6.5cow/fs/dquot.c 2004-04-14 16:22:24.000000000 +0200
@@ -573,7 +573,9 @@
if (inode->i_dquot[cnt] != NODQUOT)
goto put_it;
}
+ spin_lock(inode->i_lock);
inode->i_flags &= ~S_QUOTA;
+ spin_unlock(inode->i_lock);
put_it:
if (dquot != NODQUOT) {
if (dqput_blocks(dquot)) {
@@ -824,8 +826,11 @@
break;
}
inode->i_dquot[cnt] = dqget(inode->i_sb, id, cnt);
- if (inode->i_dquot[cnt])
+ if (inode->i_dquot[cnt]) {
+ spin_lock(inode->i_lock);
inode->i_flags |= S_QUOTA;
+ spin_unlock(inode->i_lock);
+ }
}
}
up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
@@ -839,7 +844,9 @@
{
int cnt;

+ spin_lock(inode->i_lock);
inode->i_flags &= ~S_QUOTA;
+ spin_unlock(inode->i_lock);
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
to_drop[cnt] = inode->i_dquot[cnt];
inode->i_dquot[cnt] = NODQUOT;
@@ -1174,6 +1181,7 @@
return 0;
}

+#define SAFE_FLAGS (S_QUOTA | S_NOQUOTA | S_NOATIME)
int vfs_quota_on(struct super_block *sb, int type, int format_id, char *path)
{
struct file *f;
@@ -1207,14 +1215,18 @@
error = -EBUSY;
goto out_lock;
}
- oldflags = inode->i_flags;
+ /* FIXME: this is a race for i_flags. not sure how to fix it properly,
+ * but at least it only affects the three SAFE_FLAGS now */
+ oldflags = inode_flags(inode, SAFE_FLAGS);
dqopt->files[type] = f;
error = -EINVAL;
if (!fmt->qf_ops->check_quota_file(sb, type))
goto out_file_init;
/* We don't want quota and atime on quota files (deadlocks possible) */
dquot_drop_nolock(inode);
+ spin_lock(inode->i_lock);
inode->i_flags |= S_NOQUOTA | S_NOATIME;
+ spin_unlock(inode->i_lock);

dqopt->ops[type] = fmt->qf_ops;
dqopt->info[type].dqi_format = fmt;
@@ -1233,7 +1245,10 @@
return 0;

out_file_init:
- inode->i_flags = oldflags;
+ spin_lock(inode->i_lock);
+ inode->i_flags &= ~SAFE_FLAGS;
+ inode->i_flags |= oldflags;
+ spin_unlock(inode->i_lock);
dqopt->files[type] = NULL;
out_lock:
up_write(&dqopt->dqptr_sem);
--- linux-2.6.5cow/fs/hfsplus/catalog.c~lock_flags 2004-04-14 16:22:15.000000000 +0200
+++ linux-2.6.5cow/fs/hfsplus/catalog.c 2004-04-14 16:22:24.000000000 +0200
@@ -54,11 +54,11 @@

static void hfsplus_set_perms(struct inode *inode, struct hfsplus_perm *perms)
{
- if (inode->i_flags & S_IMMUTABLE)
+ if (IS_IMMUTABLE(inode))
perms->rootflags |= HFSPLUS_FLG_IMMUTABLE;
else
perms->rootflags &= ~HFSPLUS_FLG_IMMUTABLE;
- if (inode->i_flags & S_APPEND)
+ if (IS_APPEND(inode))
perms->rootflags |= HFSPLUS_FLG_APPEND;
else
perms->rootflags &= ~HFSPLUS_FLG_APPEND;
--- linux-2.6.5cow/fs/hfsplus/dir.c~lock_flags 2004-04-14 16:22:15.000000000 +0200
+++ linux-2.6.5cow/fs/hfsplus/dir.c 2004-04-14 16:22:24.000000000 +0200
@@ -315,8 +315,11 @@
res = hfsplus_rename_cat(inode->i_ino,
dir, &dentry->d_name,
HFSPLUS_SB(sb).hidden_dir, &str);
- if (!res)
+ if (!res) {
+ spin_lock(inode->i_lock);
inode->i_flags |= S_DEAD;
+ spin_unlock(inode->i_lock);
+ }
return res;
}
res = hfsplus_delete_cat(cnid, dir, &dentry->d_name);
@@ -330,8 +333,11 @@
res = hfsplus_delete_cat(inode->i_ino, HFSPLUS_SB(sb).hidden_dir, NULL);
if (!res)
hfsplus_delete_inode(inode);
- } else
+ } else {
+ spin_lock(inode->i_lock);
inode->i_flags |= S_DEAD;
+ spin_unlock(inode->i_lock);
+ }
}
inode->i_ctime = CURRENT_TIME;
mark_inode_dirty(inode);
--- linux-2.6.5cow/fs/hfsplus/inode.c~lock_flags 2004-04-14 16:22:15.000000000 +0200
+++ linux-2.6.5cow/fs/hfsplus/inode.c 2004-04-20 16:20:21.000000000 +0200
@@ -225,6 +225,7 @@

HFSPLUS_I(inode).rootflags = perms->rootflags;
HFSPLUS_I(inode).userflags = perms->userflags;
+ spin_lock(inode->i_lock);
if (perms->rootflags & HFSPLUS_FLG_IMMUTABLE)
inode->i_flags |= S_IMMUTABLE;
else
@@ -233,10 +234,12 @@
inode->i_flags |= S_APPEND;
else
inode->i_flags &= ~S_APPEND;
+ spin_unlock(inode->i_lock);
}

static void hfsplus_set_perms(struct inode *inode, struct hfsplus_perm *perms)
{
+ spin_lock(inode->i_lock);
if (inode->i_flags & S_IMMUTABLE)
perms->rootflags |= HFSPLUS_FLG_IMMUTABLE;
else
@@ -245,6 +248,7 @@
perms->rootflags |= HFSPLUS_FLG_APPEND;
else
perms->rootflags &= ~HFSPLUS_FLG_APPEND;
+ spin_unlock(inode->i_lock);
perms->userflags = HFSPLUS_I(inode).userflags;
perms->mode = cpu_to_be16(inode->i_mode);
perms->owner = cpu_to_be32(inode->i_uid);
@@ -285,7 +289,7 @@
if (atomic_dec_and_test(&HFSPLUS_I(inode).opencnt)) {
down(&inode->i_sem);
hfsplus_file_truncate(inode);
- if (inode->i_flags & S_DEAD) {
+ if (IS_DEADDIR(inode)) {
hfsplus_delete_cat(inode->i_ino, HFSPLUS_SB(sb).hidden_dir, NULL);
hfsplus_delete_inode(inode);
}
--- linux-2.6.5cow/fs/hfsplus/ioctl.c~lock_flags 2004-04-14 16:22:15.000000000 +0200
+++ linux-2.6.5cow/fs/hfsplus/ioctl.c 2004-04-14 16:22:24.000000000 +0200
@@ -53,6 +53,7 @@
EXT2_FLAG_NODUMP))
return -EOPNOTSUPP;

+ spin_lock(inode->i_lock);
if (flags & EXT2_FLAG_IMMUTABLE) { /* EXT2_IMMUTABLE_FL */
inode->i_flags |= S_IMMUTABLE;
HFSPLUS_I(inode).rootflags |= HFSPLUS_FLG_IMMUTABLE;
@@ -67,6 +68,7 @@
inode->i_flags &= ~S_APPEND;
HFSPLUS_I(inode).rootflags &= ~HFSPLUS_FLG_APPEND;
}
+ spin_unlock(inode->i_lock);
if (flags & EXT2_FLAG_NODUMP) /* EXT2_NODUMP_FL */
HFSPLUS_I(inode).userflags |= HFSPLUS_FLG_NODUMP;
else
--- linux-2.6.5cow/fs/smbfs/file.c~lock_flags 2004-04-14 16:22:15.000000000 +0200
+++ linux-2.6.5cow/fs/smbfs/file.c 2004-04-15 22:03:45.000000000 +0200
@@ -230,7 +230,7 @@

VERBOSE("before read, size=%ld, flags=%x, atime=%ld\n",
(long)dentry->d_inode->i_size,
- dentry->d_inode->i_flags, dentry->d_inode->i_atime);
+ inode_flags(dentry->d_inode, -1U), dentry->d_inode->i_atime);

status = generic_file_read(file, buf, count, ppos);
out:
--- linux-2.6.5cow/fs/afs/inode.c~lock_flags 2004-04-14 16:22:15.000000000 +0200
+++ linux-2.6.5cow/fs/afs/inode.c 2004-04-14 16:22:24.000000000 +0200
@@ -188,7 +188,9 @@
#endif

/* okay... it's a new inode */
+ spin_lock(inode->i_lock);
inode->i_flags |= S_NOATIME;
+ spin_unlock(inode->i_lock);
vnode->flags |= AFS_VNODE_CHANGED;
ret = afs_inode_fetch_status(inode);
if (ret<0)
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/