1 diff -urp linux-2.4.21.orig/fs/ext3/ialloc.c linux-2.4.21/fs/ext3/ialloc.c
2 --- linux-2.4.21.orig/fs/ext3/ialloc.c 2007-02-16 10:23:09.000000000 +0200
3 +++ linux-2.4.21/fs/ext3/ialloc.c 2007-02-16 10:30:28.000000000 +0200
4 @@ -330,7 +330,8 @@ int ext3_itable_block_used(struct super_
5 * For other inodes, search forward from the parent directory's block
6 * group to find a free inode.
8 -struct inode * ext3_new_inode (handle_t *handle, struct inode * dir, int mode)
9 +struct inode * ext3_new_inode(handle_t *handle, const struct inode * dir,
10 + int mode, unsigned long goal)
12 struct super_block * sb;
13 struct buffer_head * bh;
14 @@ -359,7 +360,41 @@ struct inode * ext3_new_inode (handle_t
15 init_rwsem(&ei->truncate_sem);
19 + es = EXT3_SB(sb)->s_es;
22 + i = (goal - 1) / EXT3_INODES_PER_GROUP(sb);
23 + j = (goal - 1) % EXT3_INODES_PER_GROUP(sb);
24 + gdp = ext3_get_group_desc(sb, i, &bh2);
26 + bitmap_nr = load_inode_bitmap (sb, i);
27 + if (bitmap_nr < 0) {
32 + bh = EXT3_SB(sb)->s_inode_bitmap[bitmap_nr];
34 + BUFFER_TRACE(bh, "get_write_access");
35 + err = ext3_journal_get_write_access(handle, bh);
38 + if (ext3_set_bit(j, bh->b_data)) {
39 + printk(KERN_ERR "goal inode %lu unavailable\n", goal);
40 + /* Oh well, we tried. */
44 + BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
45 + err = ext3_journal_dirty_metadata(handle, bh);
48 + /* We've shortcircuited the allocation system successfully,
49 + * now finish filling in the inode.
51 + goto have_bit_and_group;
57 @@ -474,6 +509,7 @@ repeat:
62 j += i * EXT3_INODES_PER_GROUP(sb) + 1;
63 if (j < EXT3_FIRST_INO(sb) || j > le32_to_cpu(es->s_inodes_count)) {
64 ext3_error (sb, "ext3_new_inode",
65 diff -urp linux-2.4.21.orig/fs/ext3/inode.c linux-2.4.21/fs/ext3/inode.c
66 --- linux-2.4.21.orig/fs/ext3/inode.c 2007-02-16 10:23:09.000000000 +0200
67 +++ linux-2.4.21/fs/ext3/inode.c 2007-02-16 10:30:28.000000000 +0200
68 @@ -2235,7 +2235,7 @@ void ext3_truncate_thread(struct inode *
72 - new_inode = ext3_new_inode(handle, old_inode, old_inode->i_mode);
73 + new_inode = ext3_new_inode(handle, old_inode, old_inode->i_mode, 0);
74 if (IS_ERR(new_inode)) {
75 ext3_debug("truncate inode %lu directly (no new inodes)\n",
77 diff -urp linux-2.4.21.orig/fs/ext3/ioctl.c linux-2.4.21/fs/ext3/ioctl.c
78 --- linux-2.4.21.orig/fs/ext3/ioctl.c 2007-02-16 10:23:09.000000000 +0200
79 +++ linux-2.4.21/fs/ext3/ioctl.c 2007-02-16 10:30:28.000000000 +0200
80 @@ -24,6 +24,31 @@ int ext3_ioctl (struct inode * inode, st
81 ext3_debug ("cmd = %u, arg = %lu\n", cmd, arg);
84 + case EXT3_IOC_CREATE_INUM: {
86 + struct dentry *dchild, *dparent;
89 + dparent = list_entry(inode->i_dentry.next, struct dentry,
91 + snprintf(name, sizeof name, "%lu", arg);
92 + dchild = lookup_one_len(name, dparent, strlen(name));
93 + if (dchild->d_inode) {
94 + printk(KERN_ERR "%*s/%lu already exists (ino %lu)\n",
95 + dparent->d_name.len, dparent->d_name.name, arg,
96 + dchild->d_inode->i_ino);
99 + dchild->d_fsdata = (void *)arg;
100 + rc = vfs_create(inode, dchild, 0644);
102 + printk(KERN_ERR "vfs_create: %d\n", rc);
103 + else if (dchild->d_inode->i_ino != arg)
109 case EXT3_IOC_GETFLAGS:
110 flags = ei->i_flags & EXT3_FL_USER_VISIBLE;
111 return put_user(flags, (int *) arg);
112 diff -urp linux-2.4.21.orig/fs/ext3/namei.c linux-2.4.21/fs/ext3/namei.c
113 --- linux-2.4.21.orig/fs/ext3/namei.c 2007-02-16 10:23:09.000000000 +0200
114 +++ linux-2.4.21/fs/ext3/namei.c 2007-02-16 10:32:17.000000000 +0200
115 @@ -143,6 +143,14 @@ struct dx_map_entry
119 +#define LVFS_DENTRY_PARAM_MAGIC 20070216UL
120 +struct lvfs_dentry_params
122 + unsigned long p_inum;
127 #ifdef CONFIG_EXT3_INDEX
128 static inline unsigned dx_get_block (struct dx_entry *entry);
129 static void dx_set_block (struct dx_entry *entry, unsigned value);
130 @@ -1542,6 +1550,20 @@ static int ext3_add_nondir(handle_t *han
134 +static struct inode * ext3_new_inode_wantedi(handle_t *handle, struct inode *dir,
135 + int mode, struct dentry *dentry)
137 + unsigned long inum = 0;
139 + if (dentry->d_fsdata != NULL) {
140 + struct lvfs_dentry_params *param =
142 + if (param->magic == LVFS_DENTRY_PARAM_MAGIC)
143 + inum = param->p_inum;
145 + return ext3_new_inode(handle, dir, mode, inum);
149 * By the time this is called, we already have created
150 * the directory cache entry for the new file, but it
151 @@ -1565,7 +1587,7 @@ static int ext3_create (struct inode * d
155 - inode = ext3_new_inode (handle, dir, mode);
156 + inode = ext3_new_inode_wantedi (handle, dir, mode, dentry);
157 err = PTR_ERR(inode);
158 if (!IS_ERR(inode)) {
159 inode->i_op = &ext3_file_inode_operations;
160 @@ -1593,7 +1615,7 @@ static int ext3_mknod (struct inode * di
164 - inode = ext3_new_inode (handle, dir, mode);
165 + inode = ext3_new_inode_wantedi (handle, dir, mode, dentry);
166 err = PTR_ERR(inode);
167 if (!IS_ERR(inode)) {
168 init_special_inode(inode, inode->i_mode, rdev);
169 @@ -1626,7 +1648,7 @@ static int ext3_mkdir(struct inode * dir
173 - inode = ext3_new_inode (handle, dir, S_IFDIR | mode);
174 + inode = ext3_new_inode_wantedi (handle, dir, S_IFDIR | mode, dentry);
175 err = PTR_ERR(inode);
178 @@ -2056,7 +2078,7 @@ static int ext3_symlink (struct inode *
182 - inode = ext3_new_inode (handle, dir, S_IFLNK|S_IRWXUGO);
183 + inode = ext3_new_inode_wantedi (handle, dir, S_IFLNK|S_IRWXUGO, dentry);
184 err = PTR_ERR(inode);
187 diff -urp linux-2.4.21.orig/include/linux/ext3_fs.h linux-2.4.21/include/linux/ext3_fs.h
188 --- linux-2.4.21.orig/include/linux/ext3_fs.h 2007-02-16 10:23:09.000000000 +0200
189 +++ linux-2.4.21/include/linux/ext3_fs.h 2007-02-16 10:30:28.000000000 +0200
190 @@ -204,6 +204,7 @@ struct ext3_group_desc
191 #define EXT3_IOC_SETFLAGS _IOW('f', 2, long)
192 #define EXT3_IOC_GETVERSION _IOR('f', 3, long)
193 #define EXT3_IOC_SETVERSION _IOW('f', 4, long)
194 +/* EXT3_IOC_CREATE_INUM at bottom of file (visible to kernel and user). */
195 #define EXT3_IOC_GETVERSION_OLD _IOR('v', 1, long)
196 #define EXT3_IOC_SETVERSION_OLD _IOW('v', 2, long)
197 #ifdef CONFIG_JBD_DEBUG
198 @@ -671,7 +672,8 @@ extern int ext3fs_dirhash(const char *na
199 dx_hash_info *hinfo);
202 -extern struct inode * ext3_new_inode (handle_t *, struct inode *, int);
203 +extern struct inode * ext3_new_inode (handle_t *, const struct inode *, int,
205 extern void ext3_free_inode (handle_t *, struct inode *);
206 extern struct inode * ext3_orphan_get (struct super_block *, unsigned long);
207 extern unsigned long ext3_count_free_inodes (struct super_block *);
208 @@ -763,4 +765,5 @@ extern struct inode_operations ext3_fast
210 #endif /* __KERNEL__ */
212 +#define EXT3_IOC_CREATE_INUM _IOW('f', 5, long)
213 #endif /* _LINUX_EXT3_FS_H */