contents.c revision 6bd2b5d80db5630cb73e3e5a4be3b38afa241c5a
1ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross/*
2ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross * Copyright (C) 2010 The Android Open Source Project
3ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross *
4ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross * Licensed under the Apache License, Version 2.0 (the "License");
5ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross * you may not use this file except in compliance with the License.
6ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross * You may obtain a copy of the License at
7ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross *
8ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross *      http://www.apache.org/licenses/LICENSE-2.0
9ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross *
10ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross * Unless required by applicable law or agreed to in writing, software
11ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross * distributed under the License is distributed on an "AS IS" BASIS,
12ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross * See the License for the specific language governing permissions and
14ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross * limitations under the License.
15ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross */
16ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
17ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross#include <sys/stat.h>
18ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross#include <string.h>
19ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross#include <stdio.h>
20ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
21ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross#include "ext4_utils.h"
22ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross#include "ext4.h"
23ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross#include "make_ext4fs.h"
24ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross#include "allocate.h"
25ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross#include "contents.h"
26ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross#include "extent.h"
27ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross#include "indirect.h"
28ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
29ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic u32 dentry_size(u32 entries, struct dentry *dentries)
30ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
31ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 len = 24;
32ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	unsigned int i;
336bd2b5d80db5630cb73e3e5a4be3b38afa241c5aColin Cross	unsigned int dentry_len;
34ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
35ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	for (i = 0; i < entries; i++) {
366bd2b5d80db5630cb73e3e5a4be3b38afa241c5aColin Cross		dentry_len = 8 + ALIGN(strlen(dentries[i].filename), 4);
37ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		if (len % info.block_size + dentry_len > info.block_size)
38ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross			len += info.block_size - (len % info.block_size);
39ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		len += dentry_len;
40ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
41ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
42ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	return len;
43ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
44ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
45ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic struct ext4_dir_entry_2 *add_dentry(u8 *data, u32 *offset,
46ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		struct ext4_dir_entry_2 *prev, u32 inode, const char *name,
47ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		u8 file_type)
48ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
49ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u8 name_len = strlen(name);
506bd2b5d80db5630cb73e3e5a4be3b38afa241c5aColin Cross	u16 rec_len = 8 + ALIGN(name_len, 4);
51ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	struct ext4_dir_entry_2 *dentry;
52ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
53ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 start_block = *offset / info.block_size;
54ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 end_block = (*offset + rec_len) / info.block_size;
55ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (start_block != end_block) {
56ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		/* Adding this dentry will cross a block boundary, so pad the previous
57ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		   dentry to the block boundary */
58ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		if (!prev)
59ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross			critical_error("no prev");
60ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		prev->rec_len += end_block * info.block_size - *offset;
61ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		*offset = end_block * info.block_size;
62ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
63ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
64ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	dentry = (struct ext4_dir_entry_2 *)(data + *offset);
65ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	dentry->inode = inode;
66ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	dentry->rec_len = rec_len;
67ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	dentry->name_len = name_len;
68ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	dentry->file_type = file_type;
69ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	memcpy(dentry->name, name, name_len);
70ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
71ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	*offset += rec_len;
72ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	return dentry;
73ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
74ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
75ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross/* Creates a directory structure for an array of directory entries, dentries,
76ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross   and stores the location of the structure in an inode.  The new inode's
77ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross   .. link is set to dir_inode_num.  Stores the location of the inode number
78ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross   of each directory entry into dentries[i].inode, to be filled in later
79ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross   when the inode for the entry is allocated.  Returns the inode number of the
80ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross   new directory */
81ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossu32 make_directory(u32 dir_inode_num, u32 entries, struct dentry *dentries,
828aef66d2125af8de7672a12895276802fcc1948fColin Cross	u32 dirs)
83ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
84ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	struct ext4_inode *inode;
856bd2b5d80db5630cb73e3e5a4be3b38afa241c5aColin Cross	u32 blocks;
866bd2b5d80db5630cb73e3e5a4be3b38afa241c5aColin Cross	u32 len;
87ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 offset = 0;
88ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 inode_num;
89ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u8 *data;
90ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	unsigned int i;
91ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	struct ext4_dir_entry_2 *dentry;
92ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
936bd2b5d80db5630cb73e3e5a4be3b38afa241c5aColin Cross	blocks = DIV_ROUND_UP(dentry_size(entries, dentries), info.block_size);
946bd2b5d80db5630cb73e3e5a4be3b38afa241c5aColin Cross	len = blocks * info.block_size;
956bd2b5d80db5630cb73e3e5a4be3b38afa241c5aColin Cross
96ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (dir_inode_num) {
97ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		inode_num = allocate_inode(info);
98ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	} else {
99ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		dir_inode_num = EXT4_ROOT_INO;
100ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		inode_num = EXT4_ROOT_INO;
101ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
102ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
103ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (inode_num == EXT4_ALLOCATE_FAILED) {
104ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		error("failed to allocate inode\n");
105ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return EXT4_ALLOCATE_FAILED;
106ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
107ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
108ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	add_directory(inode_num);
109ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
110ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode = get_inode(inode_num);
111ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (inode == NULL) {
112ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		error("failed to get inode %u", inode_num);
113ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return EXT4_ALLOCATE_FAILED;
114ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
115ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
116ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	data = inode_allocate_data_extents(inode, len, len);
117ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (data == NULL) {
118ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		error("failed to allocate %llu extents", len);
119ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return EXT4_ALLOCATE_FAILED;
120ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
121ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
122ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_mode = S_IFDIR;
123ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_links_count = dirs + 2;
124ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_flags |= aux_info.default_i_flags;
125ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
126ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	dentry = NULL;
127ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
128ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	dentry = add_dentry(data, &offset, NULL, inode_num, ".", EXT4_FT_DIR);
129ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (!dentry) {
130ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		error("failed to add . directory");
131ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return EXT4_ALLOCATE_FAILED;
132ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
133ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
134ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	dentry = add_dentry(data, &offset, dentry, dir_inode_num, "..", EXT4_FT_DIR);
135ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (!dentry) {
136ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		error("failed to add .. directory");
137ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return EXT4_ALLOCATE_FAILED;
138ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
139ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
140ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	for (i = 0; i < entries; i++) {
1416bd2b5d80db5630cb73e3e5a4be3b38afa241c5aColin Cross		dentry = add_dentry(data, &offset, dentry, 0,
1426bd2b5d80db5630cb73e3e5a4be3b38afa241c5aColin Cross				dentries[i].filename, dentries[i].file_type);
1436bd2b5d80db5630cb73e3e5a4be3b38afa241c5aColin Cross		if (offset > len || (offset == len && i != entries - 1))
1446bd2b5d80db5630cb73e3e5a4be3b38afa241c5aColin Cross			critical_error("internal error: dentry for %s ends at %d, past %d\n",
1456bd2b5d80db5630cb73e3e5a4be3b38afa241c5aColin Cross				dentries[i].filename, offset, len);
146ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		dentries[i].inode = &dentry->inode;
147ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		if (!dentry) {
148ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross			error("failed to add directory");
149ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross			return EXT4_ALLOCATE_FAILED;
150ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		}
151ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
152ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
153ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	dentry = (struct ext4_dir_entry_2 *)(data + offset);
154ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	dentry->inode = 0;
155ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	dentry->rec_len = len - offset;
156ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	dentry->name_len = 0;
157ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	dentry->file_type = EXT4_FT_UNKNOWN;
158ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
159ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	return inode_num;
160ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
161ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
162ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross/* Creates a file on disk.  Returns the inode number of the new file */
163ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossu32 make_file(const char *filename, u64 len)
164ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
165ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	struct ext4_inode *inode;
166ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 inode_num;
167ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
168ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode_num = allocate_inode(info);
169ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (inode_num == EXT4_ALLOCATE_FAILED) {
170ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		error("failed to allocate inode\n");
171ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return EXT4_ALLOCATE_FAILED;
172ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
173ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
174ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode = get_inode(inode_num);
175ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (inode == NULL) {
176ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		error("failed to get inode %u", inode_num);
177ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return EXT4_ALLOCATE_FAILED;
178ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
179ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
180cf5c39c1851f8826264822414dbab31c1aeaeec6Colin Cross	if (len > 0)
181cf5c39c1851f8826264822414dbab31c1aeaeec6Colin Cross		inode_allocate_file_extents(inode, len, filename);
182ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
183ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_mode = S_IFREG;
184ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_links_count = 1;
185ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_flags |= aux_info.default_i_flags;
186ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
187ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	return inode_num;
188ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
189ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
190ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross/* Creates a file on disk.  Returns the inode number of the new file */
191ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossu32 make_link(const char *filename, const char *link)
192ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
193ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	struct ext4_inode *inode;
194ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 inode_num;
195ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 len = strlen(link);
196ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
197ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode_num = allocate_inode(info);
198ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (inode_num == EXT4_ALLOCATE_FAILED) {
199ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		error("failed to allocate inode\n");
200ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return EXT4_ALLOCATE_FAILED;
201ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
202ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
203ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode = get_inode(inode_num);
204ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (inode == NULL) {
205ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		error("failed to get inode %u", inode_num);
206ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return EXT4_ALLOCATE_FAILED;
207ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
208ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
209ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_mode = S_IFLNK;
210ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_links_count = 1;
211ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_flags |= aux_info.default_i_flags;
212ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_size_lo = len;
213ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
214ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (len + 1 <= sizeof(inode->i_block)) {
215ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		/* Fast symlink */
216ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		memcpy((char*)inode->i_block, link, len);
217ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	} else {
218ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		u8 *data = inode_allocate_data_indirect(inode, info.block_size, info.block_size);
219ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		memcpy(data, link, len);
220ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		inode->i_blocks_lo = info.block_size / 512;
221ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
222ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
223ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	return inode_num;
224ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
225ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
226de61f980c7b034eefac6e0ace718b3c1eb3f6252Colin Crossint inode_set_permissions(u32 inode_num, u16 mode, u16 uid, u16 gid, u32 mtime)
227ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
228ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	struct ext4_inode *inode = get_inode(inode_num);
229ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
230ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (!inode)
231ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return -1;
232ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
233ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_mode |= mode;
234ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_uid = uid;
235ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_gid = gid;
236de61f980c7b034eefac6e0ace718b3c1eb3f6252Colin Cross	inode->i_mtime = mtime;
237de61f980c7b034eefac6e0ace718b3c1eb3f6252Colin Cross	inode->i_atime = mtime;
238de61f980c7b034eefac6e0ace718b3c1eb3f6252Colin Cross	inode->i_ctime = mtime;
239ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
240ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	return 0;
241ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
242