diff -NurP --minimal linux-2.4.23-pre4/fs/ext2/ialloc.c linux-2.4.23-pre4-ctx17d/fs/ext2/ialloc.c
--- linux-2.4.23-pre4/fs/ext2/ialloc.c	2003-06-13 16:51:37.000000000 +0200
+++ linux-2.4.23-pre4-ctx17d/fs/ext2/ialloc.c	2003-09-13 15:24:22.000000000 +0200
@@ -388,7 +388,7 @@
 	inode->u.ext2_i.i_new_inode = 1;
 	inode->u.ext2_i.i_flags = dir->u.ext2_i.i_flags & ~EXT2_BTREE_FL;
 	if (S_ISLNK(mode))
-		inode->u.ext2_i.i_flags &= ~(EXT2_IMMUTABLE_FL|EXT2_APPEND_FL);
+		inode->u.ext2_i.i_flags &= ~(EXT2_IMMUTABLE_FILE_FL|EXT2_IMMUTABLE_LINK_FL|EXT2_APPEND_FL);
 	inode->u.ext2_i.i_block_group = group;
 	ext2_set_inode_flags(inode);
 	insert_inode_hash(inode);
diff -NurP --minimal linux-2.4.23-pre4/fs/ext2/inode.c linux-2.4.23-pre4-ctx17d/fs/ext2/inode.c
--- linux-2.4.23-pre4/fs/ext2/inode.c	2003-06-13 16:51:37.000000000 +0200
+++ linux-2.4.23-pre4-ctx17d/fs/ext2/inode.c	2003-09-13 15:24:22.000000000 +0200
@@ -46,6 +46,8 @@
 	ext2_discard_prealloc (inode);
 }
 
+static void ext2_truncate_nocheck (struct inode * inode);
+
 /*
  * Called at the last iput() if i_nlink is zero.
  */
@@ -62,7 +64,7 @@
 	ext2_update_inode(inode, IS_SYNC(inode));
 	inode->i_size = 0;
 	if (inode->i_blocks)
-		ext2_truncate (inode);
+		ext2_truncate_nocheck (inode);
 	ext2_free_inode (inode);
 
 	unlock_kernel();
@@ -786,7 +788,7 @@
 		ext2_free_data(inode, p, q);
 }
 
-void ext2_truncate (struct inode * inode)
+static void ext2_truncate_nocheck (struct inode * inode)
 {
 	u32 *i_data = inode->u.ext2_i.i_data;
 	int addr_per_block = EXT2_ADDR_PER_BLOCK(inode->i_sb);
@@ -801,8 +803,6 @@
 	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
 	    S_ISLNK(inode->i_mode)))
 		return;
-	if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
-		return;
 
 	ext2_discard_prealloc(inode);
 
@@ -877,17 +877,26 @@
 	}
 }
 
+void ext2_truncate (struct inode * inode)
+{
+	if (IS_APPEND(inode) || IS_IMMUTABLE_FILE(inode))
+		return;
+	ext2_truncate_nocheck (inode);
+}
+
 void ext2_set_inode_flags(struct inode *inode)
 {
 	unsigned int flags = inode->u.ext2_i.i_flags;
 
-	inode->i_flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME);
+	inode->i_flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE_FILE|S_IMMUTABLE_LINK|S_NOATIME);
 	if (flags & EXT2_SYNC_FL)
 		inode->i_flags |= S_SYNC;
 	if (flags & EXT2_APPEND_FL)
 		inode->i_flags |= S_APPEND;
-	if (flags & EXT2_IMMUTABLE_FL)
-		inode->i_flags |= S_IMMUTABLE;
+	if (flags & EXT2_IMMUTABLE_FILE_FL)
+		inode->i_flags |= S_IMMUTABLE_FILE;
+	if (flags & EXT2_IMMUTABLE_LINK_FL)
+		inode->i_flags |= S_IMMUTABLE_LINK;
 	if (flags & EXT2_NOATIME_FL)
 		inode->i_flags |= S_NOATIME;
 }
diff -NurP --minimal linux-2.4.23-pre4/fs/ext2/ioctl.c linux-2.4.23-pre4-ctx17d/fs/ext2/ioctl.c
--- linux-2.4.23-pre4/fs/ext2/ioctl.c	2003-06-13 16:51:37.000000000 +0200
+++ linux-2.4.23-pre4-ctx17d/fs/ext2/ioctl.c	2003-09-13 15:24:22.000000000 +0200
@@ -39,12 +39,12 @@
 		oldflags = inode->u.ext2_i.i_flags;
 
 		/*
-		 * The IMMUTABLE and APPEND_ONLY flags can only be changed by
-		 * the relevant capability.
+		 * The IMMUTABLE_* and APPEND_ONLY flags can only be changed
+		 * by the relevant capability.
 		 *
 		 * This test looks nicer. Thanks to Pauline Middelink
 		 */
-		if ((flags ^ oldflags) & (EXT2_APPEND_FL | EXT2_IMMUTABLE_FL)) {
+		if ((flags ^ oldflags) & (EXT2_APPEND_FL | EXT2_IMMUTABLE_FILE_FL | EXT2_IMMUTABLE_LINK_FL)) {
 			if (!capable(CAP_LINUX_IMMUTABLE))
 				return -EPERM;
 		}
diff -NurP --minimal linux-2.4.23-pre4/fs/ext3/ialloc.c linux-2.4.23-pre4-ctx17d/fs/ext3/ialloc.c
--- linux-2.4.23-pre4/fs/ext3/ialloc.c	2003-06-13 16:51:37.000000000 +0200
+++ linux-2.4.23-pre4-ctx17d/fs/ext3/ialloc.c	2003-09-13 15:24:22.000000000 +0200
@@ -485,7 +485,7 @@
 	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
 	inode->u.ext3_i.i_flags = dir->u.ext3_i.i_flags & ~EXT3_INDEX_FL;
 	if (S_ISLNK(mode))
-		inode->u.ext3_i.i_flags &= ~(EXT3_IMMUTABLE_FL|EXT3_APPEND_FL);
+		inode->u.ext3_i.i_flags &= ~(EXT3_IMMUTABLE_FILE_FL|EXT3_IMMUTABLE_LINK_FL|EXT3_APPEND_FL);
 #ifdef EXT3_FRAGMENTS
 	inode->u.ext3_i.i_faddr = 0;
 	inode->u.ext3_i.i_frag_no = 0;
diff -NurP --minimal linux-2.4.23-pre4/fs/ext3/inode.c linux-2.4.23-pre4-ctx17d/fs/ext3/inode.c
--- linux-2.4.23-pre4/fs/ext3/inode.c	2003-08-25 20:32:18.000000000 +0200
+++ linux-2.4.23-pre4-ctx17d/fs/ext3/inode.c	2003-09-13 15:24:22.000000000 +0200
@@ -172,6 +172,7 @@
 	ext3_discard_prealloc (inode);
 }
 
+static void ext3_truncate_nocheck (struct inode *inode);
 /*
  * Called at the last iput() if i_nlink is zero.
  */
@@ -201,7 +202,7 @@
 		handle->h_sync = 1;
 	inode->i_size = 0;
 	if (inode->i_blocks)
-		ext3_truncate(inode);
+		ext3_truncate_nocheck(inode);
 	/*
 	 * Kill off the orphan record which ext3_truncate created.
 	 * AKPM: I think this can be inside the above `if'.
@@ -1854,7 +1855,7 @@
  * ext3_truncate() run will find them and release them.
  */
 
-void ext3_truncate(struct inode * inode)
+static void ext3_truncate_nocheck(struct inode * inode)
 {
 	handle_t *handle;
 	u32 *i_data = inode->u.ext3_i.i_data;
@@ -1870,8 +1871,6 @@
 	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
 	    S_ISLNK(inode->i_mode)))
 		return;
-	if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
-		return;
 
 	ext3_discard_prealloc(inode);
 
@@ -2001,6 +2000,13 @@
 	ext3_journal_stop(handle, inode);
 }
 
+void ext3_truncate(struct inode * inode)
+{
+	if (IS_APPEND(inode) || IS_IMMUTABLE_FILE(inode))
+		return;
+	ext3_truncate_nocheck (inode);
+}
+
 /* 
  * ext3_get_inode_loc returns with an extra refcount against the
  * inode's underlying buffer_head on success. 
@@ -2072,13 +2078,15 @@
 {
 	unsigned int flags = inode->u.ext3_i.i_flags;
 
-	inode->i_flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME);
+	inode->i_flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE_FILE|S_IMMUTABLE_LINK|S_NOATIME);
 	if (flags & EXT3_SYNC_FL)
 		inode->i_flags |= S_SYNC;
 	if (flags & EXT3_APPEND_FL)
 		inode->i_flags |= S_APPEND;
-	if (flags & EXT3_IMMUTABLE_FL)
-		inode->i_flags |= S_IMMUTABLE;
+	if (flags & EXT3_IMMUTABLE_FILE_FL)
+		inode->i_flags |= S_IMMUTABLE_FILE;
+	if (flags & EXT3_IMMUTABLE_LINK_FL)
+		inode->i_flags |= S_IMMUTABLE_LINK;
 	if (flags & EXT3_NOATIME_FL)
 		inode->i_flags |= S_NOATIME;
 }
diff -NurP --minimal linux-2.4.23-pre4/fs/ext3/ioctl.c linux-2.4.23-pre4-ctx17d/fs/ext3/ioctl.c
--- linux-2.4.23-pre4/fs/ext3/ioctl.c	2003-06-13 16:51:37.000000000 +0200
+++ linux-2.4.23-pre4-ctx17d/fs/ext3/ioctl.c	2003-09-13 15:24:22.000000000 +0200
@@ -48,12 +48,12 @@
 		jflag = flags & EXT3_JOURNAL_DATA_FL;
 
 		/*
-		 * The IMMUTABLE and APPEND_ONLY flags can only be changed by
-		 * the relevant capability.
+		 * The IMMUTABLE_* and APPEND_ONLY flags can only be changed
+		 * by the relevant capability.
 		 *
 		 * This test looks nicer. Thanks to Pauline Middelink
 		 */
-		if ((flags ^ oldflags) & (EXT3_APPEND_FL | EXT3_IMMUTABLE_FL)) {
+		if ((flags ^ oldflags) & (EXT3_APPEND_FL | EXT3_IMMUTABLE_FILE_FL | EXT3_IMMUTABLE_LINK_FL)) {
 			if (!capable(CAP_LINUX_IMMUTABLE))
 				return -EPERM;
 		}
diff -NurP --minimal linux-2.4.23-pre4/fs/fat/file.c linux-2.4.23-pre4-ctx17d/fs/fat/file.c
--- linux-2.4.23-pre4/fs/fat/file.c	2001-08-12 19:56:56.000000000 +0200
+++ linux-2.4.23-pre4-ctx17d/fs/fat/file.c	2003-09-13 15:24:22.000000000 +0200
@@ -119,7 +119,7 @@
 	/* Why no return value?  Surely the disk could fail... */
 	if (IS_RDONLY (inode))
 		return /* -EPERM */;
-	if (IS_IMMUTABLE(inode))
+	if (IS_IMMUTABLE_FILE(inode))
 		return /* -EPERM */;
 	cluster = 1 << sbi->cluster_bits;
 	/* 
diff -NurP --minimal linux-2.4.23-pre4/fs/fat/inode.c linux-2.4.23-pre4-ctx17d/fs/fat/inode.c
--- linux-2.4.23-pre4/fs/fat/inode.c	2003-08-25 20:32:18.000000000 +0200
+++ linux-2.4.23-pre4-ctx17d/fs/fat/inode.c	2003-09-13 15:24:22.000000000 +0200
@@ -950,7 +950,7 @@
 	}
 	if(de->attr & ATTR_SYS)
 		if (sbi->options.sys_immutable)
-			inode->i_flags |= S_IMMUTABLE;
+			inode->i_flags |= S_IMMUTABLE_FILE;
 	MSDOS_I(inode)->i_attrs = de->attr & ATTR_UNUSED;
 	/* this is as close to the truth as we can get ... */
 	inode->i_blksize = 1 << sbi->cluster_bits;
diff -NurP --minimal linux-2.4.23-pre4/fs/hpfs/file.c linux-2.4.23-pre4-ctx17d/fs/hpfs/file.c
--- linux-2.4.23-pre4/fs/hpfs/file.c	2001-08-13 02:37:53.000000000 +0200
+++ linux-2.4.23-pre4-ctx17d/fs/hpfs/file.c	2003-09-13 15:24:22.000000000 +0200
@@ -60,7 +60,7 @@
 
 void hpfs_truncate(struct inode *i)
 {
-	if (IS_IMMUTABLE(i)) return /*-EPERM*/;
+	if (IS_IMMUTABLE_FILE(i)) return /*-EPERM*/;
 	i->i_hpfs_n_secs = 0;
 	i->i_blocks = 1 + ((i->i_size + 511) >> 9);
 	i->u.hpfs_i.mmu_private = i->i_size;
diff -NurP --minimal linux-2.4.23-pre4/fs/intermezzo/vfs.c linux-2.4.23-pre4-ctx17d/fs/intermezzo/vfs.c
--- linux-2.4.23-pre4/fs/intermezzo/vfs.c	2003-06-13 16:51:37.000000000 +0200
+++ linux-2.4.23-pre4-ctx17d/fs/intermezzo/vfs.c	2003-09-13 15:24:22.000000000 +0200
@@ -140,7 +140,7 @@
         if (IS_APPEND(dir))
                 return -EPERM;
         if (check_sticky(dir, victim->d_inode)||IS_APPEND(victim->d_inode)||
-            IS_IMMUTABLE(victim->d_inode))
+            IS_IMMUTABLE_LINK(victim->d_inode))
                 return -EPERM;
         if (isdir) {
                 if (!S_ISDIR(victim->d_inode->i_mode))
@@ -262,7 +262,7 @@
                         return -EROFS;
                 }
 
-                if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) {
+                if (IS_IMMUTABLE_FILE(inode) || IS_APPEND(inode)) {
                         EXIT;
                         return -EPERM;
                 }
@@ -377,7 +377,7 @@
                 return -EROFS;
         }
 
-        if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) {
+        if (IS_IMMUTABLE_FILE(inode) || IS_APPEND(inode)) {
                 EXIT;
                 return -EPERM;
         }
@@ -772,7 +772,7 @@
          * A link to an append-only or immutable file cannot be created.
          */
         error = -EPERM;
-        if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) {
+        if (IS_APPEND(inode) || IS_IMMUTABLE_LINK(inode)) {
                 EXIT;
                 goto exit_lock;
         }
@@ -2362,7 +2362,7 @@
                 return -EROFS;
         }
 
-        if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) {
+        if (IS_IMMUTABLE_FILE(inode) || IS_APPEND(inode)) {
                 EXIT;
                 return -EPERM;
         }
diff -NurP --minimal linux-2.4.23-pre4/fs/jfs/xattr.c linux-2.4.23-pre4-ctx17d/fs/jfs/xattr.c
--- linux-2.4.23-pre4/fs/jfs/xattr.c	2003-09-13 00:50:16.000000000 +0200
+++ linux-2.4.23-pre4-ctx17d/fs/jfs/xattr.c	2003-09-13 15:24:22.000000000 +0200
@@ -646,7 +646,7 @@
 	if (IS_RDONLY(inode))
 		return -EROFS;
 
-	if (IS_IMMUTABLE(inode) || IS_APPEND(inode) || S_ISLNK(inode->i_mode))
+	if (IS_IMMUTABLE_FILE(inode) || IS_APPEND(inode) || S_ISLNK(inode->i_mode))
 		return -EPERM;
 
 	if((strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN) != 0) &&
diff -NurP --minimal linux-2.4.23-pre4/fs/namei.c linux-2.4.23-pre4-ctx17d/fs/namei.c
--- linux-2.4.23-pre4/fs/namei.c	2003-08-25 20:32:19.000000000 +0200
+++ linux-2.4.23-pre4-ctx17d/fs/namei.c	2003-09-13 15:24:22.000000000 +0200
@@ -163,7 +172,7 @@
 		/*
 		 * Nobody gets write access to an immutable file.
 		 */
-		if (IS_IMMUTABLE(inode))
+		if (IS_IMMUTABLE_FILE(inode))
 			return -EACCES;
 	}
 
@@ -904,8 +913,7 @@
 		return error;
 	if (IS_APPEND(dir))
 		return -EPERM;
-	if (check_sticky(dir, victim->d_inode)||IS_APPEND(victim->d_inode)||
-	    IS_IMMUTABLE(victim->d_inode))
+	if (check_sticky(dir, victim->d_inode)||IS_APPEND(victim->d_inode)||IS_IMMUTABLE_LINK(victim->d_inode))
 		return -EPERM;
 	if (isdir) {
 		if (!S_ISDIR(victim->d_inode->i_mode))
@@ -1618,7 +1626,7 @@
 	 * A link to an append-only or immutable file cannot be created.
 	 */
 	error = -EPERM;
-	if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
+	if (IS_APPEND(inode) || IS_IMMUTABLE_LINK(inode))
 		goto exit_lock;
 	if (!dir->i_op || !dir->i_op->link)
 		goto exit_lock;
diff -NurP --minimal linux-2.4.23-pre4/fs/nfsd/vfs.c linux-2.4.23-pre4-ctx17d/fs/nfsd/vfs.c
--- linux-2.4.23-pre4/fs/nfsd/vfs.c	2003-09-13 00:50:16.000000000 +0200
+++ linux-2.4.23-pre4-ctx17d/fs/nfsd/vfs.c	2003-09-13 15:24:22.000000000 +0200
@@ -1480,7 +1480,7 @@
 	if (acc == MAY_NOP)
 		return 0;
 #if 0
-	dprintk("nfsd: permission 0x%x%s%s%s%s%s%s%s mode 0%o%s%s%s\n",
+	dprintk("nfsd: permission 0x%x%s%s%s%s%s%s%s mode 0%o%s%s%s%s\n",
 		acc,
 		(acc & MAY_READ)?	" read"  : "",
 		(acc & MAY_WRITE)?	" write" : "",
@@ -1490,7 +1490,8 @@
 		(acc & MAY_LOCK)?	" lock"  : "",
 		(acc & MAY_OWNER_OVERRIDE)? " owneroverride" : "",
 		inode->i_mode,
-		IS_IMMUTABLE(inode)?	" immut" : "",
+		IS_IMMUTABLE_FILE(inode)? " immut(F)" : "",
+		IS_IMMUTABLE_LINK(inode)? " immut(L)" : "",
 		IS_APPEND(inode)?	" append" : "",
 		IS_RDONLY(inode)?	" ro" : "");
 	dprintk("      owner %d/%d user %d/%d\n",
@@ -1509,7 +1510,7 @@
 	 && (acc & (MAY_WRITE | MAY_SATTR | MAY_TRUNC))) {
 		if (EX_RDONLY(exp) || IS_RDONLY(inode))
 			return nfserr_rofs;
-		if (/* (acc & MAY_WRITE) && */ IS_IMMUTABLE(inode))
+		if (/* (acc & MAY_WRITE) && */ IS_IMMUTABLE_FILE(inode))
 			return nfserr_perm;
 	}
 	if ((acc & MAY_TRUNC) && IS_APPEND(inode))
diff -NurP --minimal linux-2.4.23-pre4/fs/open.c linux-2.4.23-pre4-ctx17d/fs/open.c
--- linux-2.4.23-pre4/fs/open.c	2003-08-25 20:32:19.000000000 +0200
+++ linux-2.4.23-pre4-ctx17d/fs/open.c	2003-09-13 15:24:22.000000000 +0200
@@ -148,7 +148,7 @@
 		goto dput_and_out;
 
 	error = -EPERM;
-	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+	if (IS_IMMUTABLE_FILE(inode) || IS_APPEND(inode))
 		goto dput_and_out;
 
 	/*
@@ -480,7 +480,7 @@
 	if (IS_RDONLY(inode))
 		goto out_putf;
 	err = -EPERM;
-	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+	if (IS_IMMUTABLE_FILE(inode) || IS_APPEND(inode))
 		goto out_putf;
 	if (mode == (mode_t) -1)
 		mode = inode->i_mode;
@@ -511,7 +511,7 @@
 		goto dput_and_out;
 
 	error = -EPERM;
-	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+	if (IS_IMMUTABLE_FILE(inode) || IS_APPEND(inode))
 		goto dput_and_out;
 
 	if (mode == (mode_t) -1)
@@ -541,7 +541,7 @@
 	if (IS_RDONLY(inode))
 		goto out;
 	error = -EPERM;
-	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+	if (IS_IMMUTABLE_FILE(inode) || IS_APPEND(inode))
 		goto out;
 	if (user == (uid_t) -1)
 		user = inode->i_uid;
diff -NurP --minimal linux-2.4.23-pre4/fs/proc/base.c linux-2.4.23-pre4-ctx17d/fs/proc/base.c
--- linux-2.4.23-pre4/fs/proc/base.c	2003-08-25 20:32:19.000000000 +0200
+++ linux-2.4.23-pre4-ctx17d/fs/proc/base.c	2003-09-13 17:19:02.000000000 +0200
@@ -1066,7 +1072,7 @@
 	inode->i_op = &proc_base_inode_operations;
 	inode->i_fop = &proc_base_operations;
 	inode->i_nlink = 3;
-	inode->i_flags|=S_IMMUTABLE;
+	inode->i_flags|=S_IMMUTABLE_FILE;
 
 	dentry->d_op = &pid_base_dentry_operations;
 	d_add(dentry, inode);
diff -NurP --minimal linux-2.4.23-pre4/fs/reiserfs/inode.c linux-2.4.23-pre4-ctx17d/fs/reiserfs/inode.c
--- linux-2.4.23-pre4/fs/reiserfs/inode.c	2003-08-25 20:32:19.000000000 +0200
+++ linux-2.4.23-pre4-ctx17d/fs/reiserfs/inode.c	2003-09-13 15:24:22.000000000 +0200
@@ -1574,7 +1574,7 @@
 
     /* symlink cannot be immutable or append only, right? */
     if( S_ISLNK( inode -> i_mode ) )
-	    inode -> i_flags &= ~ ( S_IMMUTABLE | S_APPEND );
+	    inode -> i_flags &= ~ ( S_IMMUTABLE_FILE | S_APPEND );
 
     /* item head of new item */
     ih.ih_key.k_dir_id = INODE_PKEY (dir)->k_objectid;
@@ -2177,10 +2177,14 @@
 			inode -> i_flags |= S_SYNC;
 		else
 			inode -> i_flags &= ~S_SYNC;
-		if( sd_attrs & REISERFS_IMMUTABLE_FL )
-			inode -> i_flags |= S_IMMUTABLE;
+		if( sd_attrs & REISERFS_IMMUTABLE_FILE_FL )
+			inode -> i_flags |= S_IMMUTABLE_FILE;
 		else
-			inode -> i_flags &= ~S_IMMUTABLE;
+			inode -> i_flags &= ~S_IMMUTABLE_FILE;
+		if( sd_attrs & REISERFS_IMMUTABLE_LINK_FL )
+			inode -> i_flags |= S_IMMUTABLE_LINK;
+		else
+			inode -> i_flags &= ~S_IMMUTABLE_LINK;
 		if( sd_attrs & REISERFS_APPEND_FL )
 			inode -> i_flags |= S_APPEND;
 		else
@@ -2199,10 +2203,14 @@
 void i_attrs_to_sd_attrs( struct inode *inode, __u16 *sd_attrs )
 {
 	if( reiserfs_attrs( inode -> i_sb ) ) {
-		if( inode -> i_flags & S_IMMUTABLE )
-			*sd_attrs |= REISERFS_IMMUTABLE_FL;
+		if( inode -> i_flags & S_IMMUTABLE_FILE )
+			*sd_attrs |= REISERFS_IMMUTABLE_FILE_FL;
 		else
-			*sd_attrs &= ~REISERFS_IMMUTABLE_FL;
+			*sd_attrs &= ~REISERFS_IMMUTABLE_FILE_FL;
+		if( inode -> i_flags & S_IMMUTABLE_LINK )
+			*sd_attrs |= REISERFS_IMMUTABLE_LINK_FL;
+		else
+			*sd_attrs &= ~REISERFS_IMMUTABLE_LINK_FL;
 		if( inode -> i_flags & S_SYNC )
 			*sd_attrs |= REISERFS_SYNC_FL;
 		else
diff -NurP --minimal linux-2.4.23-pre4/fs/reiserfs/ioctl.c linux-2.4.23-pre4-ctx17d/fs/reiserfs/ioctl.c
--- linux-2.4.23-pre4/fs/reiserfs/ioctl.c	2003-08-25 20:32:19.000000000 +0200
+++ linux-2.4.23-pre4-ctx17d/fs/reiserfs/ioctl.c	2003-09-13 17:19:02.000000000 +0200
@@ -51,7 +51,8 @@
 		if (get_user(flags, (int *) arg))
 			return -EFAULT;
 
-		if ( ( ( flags ^ inode->u.reiserfs_i.i_attrs) & ( REISERFS_IMMUTABLE_FL | REISERFS_APPEND_FL)) && 
+		if ( ( ( flags ^ inode->u.reiserfs_i.i_attrs) &
+		     ( REISERFS_IMMUTABLE_FILE_FL | REISERFS_IMMUTABLE_LINK_FL | REISERFS_APPEND_FL )) &&
 		     !capable( CAP_LINUX_IMMUTABLE ) )
 			return -EPERM;
 			
diff -NurP --minimal linux-2.4.23-pre4/fs/udf/inode.c linux-2.4.23-pre4-ctx17d/fs/udf/inode.c
--- linux-2.4.23-pre4/fs/udf/inode.c	2002-08-03 02:39:45.000000000 +0200
+++ linux-2.4.23-pre4-ctx17d/fs/udf/inode.c	2003-09-13 15:24:22.000000000 +0200
@@ -860,7 +860,7 @@
 	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
 			S_ISLNK(inode->i_mode)))
 		return;
-	if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
+	if (IS_APPEND(inode) || IS_IMMUTABLE_FILE(inode))
 		return;
 
 	if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
diff -NurP --minimal linux-2.4.23-pre4/fs/ufs/truncate.c linux-2.4.23-pre4-ctx17d/fs/ufs/truncate.c
--- linux-2.4.23-pre4/fs/ufs/truncate.c	2002-11-29 00:53:15.000000000 +0100
+++ linux-2.4.23-pre4-ctx17d/fs/ufs/truncate.c	2003-09-13 15:24:22.000000000 +0200
@@ -434,7 +434,7 @@
 
 	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)))
 		return;
-	if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
+	if (IS_APPEND(inode) || IS_IMMUTABLE_FILE(inode))
 		return;
 	while (1) {
 		retry = ufs_trunc_direct(inode);
diff -NurP --minimal linux-2.4.23-pre4/include/linux/capability.h linux-2.4.23-pre4-ctx17d/include/linux/capability.h
--- linux-2.4.23-pre4/include/linux/capability.h	2003-08-15 01:24:52.000000000 +0200
+++ linux-2.4.23-pre4-ctx17d/include/linux/capability.h	2003-09-13 17:19:02.000000000 +0200
@@ -130,7 +130,8 @@
 
 #define CAP_SETPCAP          8
 
-/* Allow modification of S_IMMUTABLE and S_APPEND file attributes */
+/* Allow modification of S_IMMUTABLE_* and S_APPEND file
+   attributes */
 
 #define CAP_LINUX_IMMUTABLE  9
 
diff -NurP --minimal linux-2.4.23-pre4/include/linux/ext2_fs.h linux-2.4.23-pre4-ctx17d/include/linux/ext2_fs.h
--- linux-2.4.23-pre4/include/linux/ext2_fs.h	2003-08-15 01:25:42.000000000 +0200
+++ linux-2.4.23-pre4-ctx17d/include/linux/ext2_fs.h	2003-09-13 15:55:13.000000000 +0200
@@ -187,7 +187,7 @@
 #define	EXT2_UNRM_FL			0x00000002 /* Undelete */
 #define	EXT2_COMPR_FL			0x00000004 /* Compress file */
 #define EXT2_SYNC_FL			0x00000008 /* Synchronous updates */
-#define EXT2_IMMUTABLE_FL		0x00000010 /* Immutable file */
+#define EXT2_IMMUTABLE_FILE_FL		0x00000010 /* Immutable file */
 #define EXT2_APPEND_FL			0x00000020 /* writes to file may only append */
 #define EXT2_NODUMP_FL			0x00000040 /* do not dump file */
 #define EXT2_NOATIME_FL			0x00000080 /* do not update atime */
@@ -198,10 +198,11 @@
 #define EXT2_ECOMPR_FL			0x00000800 /* Compression error */
 /* End compression flags --- maybe not all used */	
 #define EXT2_BTREE_FL			0x00001000 /* btree format dir */
+#define EXT2_IMMUTABLE_LINK_FL          0x00008000 /* Immutable link */
 #define EXT2_RESERVED_FL		0x80000000 /* reserved for ext2 lib */
 
-#define EXT2_FL_USER_VISIBLE		0x00001FFF /* User visible flags */
-#define EXT2_FL_USER_MODIFIABLE		0x000000FF /* User modifiable flags */
+#define EXT2_FL_USER_VISIBLE		0x00009FFF /* User visible flags */
+#define EXT2_FL_USER_MODIFIABLE		0x000080FF /* User modifiable flags */
 
 /*
  * ioctl commands
diff -NurP --minimal linux-2.4.23-pre4/include/linux/ext3_fs.h linux-2.4.23-pre4-ctx17d/include/linux/ext3_fs.h
--- linux-2.4.23-pre4/include/linux/ext3_fs.h	2003-08-09 16:50:43.000000000 +0200
+++ linux-2.4.23-pre4-ctx17d/include/linux/ext3_fs.h	2003-09-13 15:55:19.000000000 +0200
@@ -190,7 +190,7 @@
 #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_IMMUTABLE_FILE_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 */
@@ -203,10 +203,11 @@
 #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_IMMUTABLE_LINK_FL		0x00008000 /* Immutable link */
 #define EXT3_RESERVED_FL		0x80000000 /* reserved for ext3 lib */
 
-#define EXT3_FL_USER_VISIBLE		0x00005FFF /* User visible flags */
-#define EXT3_FL_USER_MODIFIABLE		0x000000FF /* User modifiable flags */
+#define EXT3_FL_USER_VISIBLE		0x0000DFFF /* User visible flags */
+#define EXT3_FL_USER_MODIFIABLE		0x000080FF /* User modifiable flags */
 
 /*
  * Inode dynamic state flags
diff -NurP --minimal linux-2.4.23-pre4/include/linux/fs.h linux-2.4.23-pre4-ctx17d/include/linux/fs.h
--- linux-2.4.23-pre4/include/linux/fs.h	2003-08-25 20:32:20.000000000 +0200
+++ linux-2.4.23-pre4-ctx17d/include/linux/fs.h	2003-09-13 15:52:46.000000000 +0200
@@ -132,9 +132,10 @@
 #define S_NOATIME	2	/* Do not update access times */
 #define S_QUOTA		4	/* Quota initialized for file */
 #define S_APPEND	8	/* Append-only file */
-#define S_IMMUTABLE	16	/* Immutable file */
+#define S_IMMUTABLE_FILE	16	/* Immutable file */
 #define S_DEAD		32	/* removed, but still open directory */
 #define S_NOQUOTA	64	/* Inode is not counted to quota */
+#define S_IMMUTABLE_LINK	128	/* Immutable links */
 
 /*
  * Note that nosuid etc flags are inode-specific: setting some file-system
@@ -158,7 +159,8 @@
 #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_IMMUTABLE_FILE(inode)	((inode)->i_flags & S_IMMUTABLE_FILE)
+#define IS_IMMUTABLE_LINK(inode) ((((inode)->i_flags & S_IMMUTABLE_FILE) << 3) ^ ((inode)->i_flags & S_IMMUTABLE_LINK) )
 #define IS_NOATIME(inode)	(__IS_FLG(inode, MS_NOATIME) || ((inode)->i_flags & S_NOATIME))
 #define IS_NODIRATIME(inode)	__IS_FLG(inode, MS_NODIRATIME)
 
@@ -366,8 +369,9 @@
 #define ATTR_FLAG_SYNCRONOUS	1 	/* Syncronous write */
 #define ATTR_FLAG_NOATIME	2 	/* Don't update atime */
 #define ATTR_FLAG_APPEND	4 	/* Append-only file */
-#define ATTR_FLAG_IMMUTABLE	8 	/* Immutable file */
+#define ATTR_FLAG_IMMUTABLE_FILE	8	/* Immutable file */
 #define ATTR_FLAG_NODIRATIME	16 	/* Don't update atime for directory */
+#define ATTR_FLAG_IMMUTABLE_LINK	32	/* Immutable file */
 
 /*
  * Includes for diskquotas and mount structures.
diff -NurP --minimal linux-2.4.23-pre4/include/linux/reiserfs_fs.h linux-2.4.23-pre4-ctx17d/include/linux/reiserfs_fs.h
--- linux-2.4.23-pre4/include/linux/reiserfs_fs.h	2003-08-25 20:32:20.000000000 +0200
+++ linux-2.4.23-pre4-ctx17d/include/linux/reiserfs_fs.h	2003-09-13 15:24:22.000000000 +0200
@@ -866,7 +866,8 @@
 
 /* we want common flags to have the same values as in ext2,
    so chattr(1) will work without problems */
-#define REISERFS_IMMUTABLE_FL EXT2_IMMUTABLE_FL
+#define REISERFS_IMMUTABLE_FILE_FL EXT2_IMMUTABLE_FILE_FL
+#define REISERFS_IMMUTABLE_LINK_FL EXT2_IMMUTABLE_LINK_FL
 #define REISERFS_APPEND_FL    EXT2_APPEND_FL
 #define REISERFS_SYNC_FL      EXT2_SYNC_FL
 #define REISERFS_NOATIME_FL   EXT2_NOATIME_FL
@@ -883,7 +884,8 @@
 #define REISERFS_NOTAIL_FL    (0x00008000) /* EXT2_NOTAIL_FL */
 
 /* persistent flags that file inherits from the parent directory */
-#define REISERFS_INHERIT_MASK ( REISERFS_IMMUTABLE_FL |	\
+#define REISERFS_INHERIT_MASK ( REISERFS_IMMUTABLE_FILE_FL |	\
+				REISERFS_IMMUTABLE_LINK_FL |	\
 				REISERFS_SYNC_FL |	\
 				REISERFS_NOATIME_FL |	\
 				REISERFS_NODUMP_FL |	\
