Linux-2.6.12-rc2

Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.

Let it rip!
diff --git a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c
new file mode 100644
index 0000000..94dc424
--- /dev/null
+++ b/fs/reiserfs/ioctl.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
+ */
+
+#include <linux/fs.h>
+#include <linux/reiserfs_fs.h>
+#include <linux/time.h>
+#include <asm/uaccess.h>
+#include <linux/pagemap.h>
+#include <linux/smp_lock.h>
+
+static int reiserfs_unpack (struct inode * inode, struct file * filp);
+
+/*
+** reiserfs_ioctl - handler for ioctl for inode
+** supported commands:
+**  1) REISERFS_IOC_UNPACK - try to unpack tail from direct item into indirect
+**                           and prevent packing file (argument arg has to be non-zero)
+**  2) REISERFS_IOC_[GS]ETFLAGS, REISERFS_IOC_[GS]ETVERSION
+**  3) That's all for a while ...
+*/
+int reiserfs_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
+		unsigned long arg)
+{
+	unsigned int flags;
+
+	switch (cmd) {
+	    case REISERFS_IOC_UNPACK:
+		if( S_ISREG( inode -> i_mode ) ) {
+		if (arg)
+		    return reiserfs_unpack (inode, filp);
+			else
+				return 0;
+		} else
+			return -ENOTTY;
+	/* following two cases are taken from fs/ext2/ioctl.c by Remy
+	   Card (card@masi.ibp.fr) */
+	case REISERFS_IOC_GETFLAGS:
+		flags = REISERFS_I(inode) -> i_attrs;
+		i_attrs_to_sd_attrs( inode, ( __u16 * ) &flags );
+		return put_user(flags, (int __user *) arg);
+	case REISERFS_IOC_SETFLAGS: {
+		if (IS_RDONLY(inode))
+			return -EROFS;
+
+		if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
+			return -EPERM;
+
+		if (get_user(flags, (int __user *) arg))
+			return -EFAULT;
+
+		if ( ( ( flags ^ REISERFS_I(inode) -> i_attrs) & ( REISERFS_IMMUTABLE_FL | REISERFS_APPEND_FL)) &&
+		     !capable( CAP_LINUX_IMMUTABLE ) )
+			return -EPERM;
+			
+		if( ( flags & REISERFS_NOTAIL_FL ) &&
+		    S_ISREG( inode -> i_mode ) ) {
+				int result;
+
+				result = reiserfs_unpack( inode, filp );
+				if( result )
+					return result;
+		}
+		sd_attrs_to_i_attrs( flags, inode );
+		REISERFS_I(inode) -> i_attrs = flags;
+		inode->i_ctime = CURRENT_TIME_SEC;
+		mark_inode_dirty(inode);
+		return 0;
+	}
+	case REISERFS_IOC_GETVERSION:
+		return put_user(inode->i_generation, (int __user *) arg);
+	case REISERFS_IOC_SETVERSION:
+		if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
+			return -EPERM;
+		if (IS_RDONLY(inode))
+			return -EROFS;
+		if (get_user(inode->i_generation, (int __user *) arg))
+			return -EFAULT;	
+		inode->i_ctime = CURRENT_TIME_SEC;
+		mark_inode_dirty(inode);
+		return 0;
+	default:
+		return -ENOTTY;
+	}
+}
+
+/*
+** reiserfs_unpack
+** Function try to convert tail from direct item into indirect.
+** It set up nopack attribute in the REISERFS_I(inode)->nopack
+*/
+static int reiserfs_unpack (struct inode * inode, struct file * filp)
+{
+    int retval = 0;
+    int index ;
+    struct page *page ;
+    struct address_space *mapping ;
+    unsigned long write_from ;
+    unsigned long blocksize = inode->i_sb->s_blocksize ;
+    	
+    if (inode->i_size == 0) {
+        REISERFS_I(inode)->i_flags |= i_nopack_mask;
+        return 0 ;
+    }
+    /* ioctl already done */
+    if (REISERFS_I(inode)->i_flags & i_nopack_mask) {
+        return 0 ;
+    }
+    reiserfs_write_lock(inode->i_sb);
+
+    /* we need to make sure nobody is changing the file size beneath
+    ** us
+    */
+    down(&inode->i_sem) ;
+
+    write_from = inode->i_size & (blocksize - 1) ;
+    /* if we are on a block boundary, we are already unpacked.  */
+    if ( write_from == 0) {
+	REISERFS_I(inode)->i_flags |= i_nopack_mask;
+	goto out ;
+    }
+
+    /* we unpack by finding the page with the tail, and calling
+    ** reiserfs_prepare_write on that page.  This will force a 
+    ** reiserfs_get_block to unpack the tail for us.
+    */
+    index = inode->i_size >> PAGE_CACHE_SHIFT ;
+    mapping = inode->i_mapping ;
+    page = grab_cache_page(mapping, index) ;
+    retval = -ENOMEM;
+    if (!page) {
+        goto out ;
+    }
+    retval = mapping->a_ops->prepare_write(NULL, page, write_from, write_from) ;
+    if (retval)
+        goto out_unlock ;
+
+    /* conversion can change page contents, must flush */
+    flush_dcache_page(page) ;
+    retval = mapping->a_ops->commit_write(NULL, page, write_from, write_from) ;
+    REISERFS_I(inode)->i_flags |= i_nopack_mask;
+
+out_unlock:
+    unlock_page(page) ;
+    page_cache_release(page) ;
+
+out:
+    up(&inode->i_sem) ;
+    reiserfs_write_unlock(inode->i_sb);
+    return retval;
+}