diff options
author | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2008-07-14 12:08:37 -0400 |
---|---|---|
committer | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2008-07-15 10:35:15 -0400 |
commit | 1e51764a3c2ac05a23a22b2a95ddee4d9bffb16d (patch) | |
tree | 919debdd48aef9eee9ff0e8f465ef2649325b993 /fs/ubifs/dir.c | |
parent | e56a99d5a42dcb91e622ae7a0289d8fb2ddabffb (diff) |
UBIFS: add new flash file system
This is a new flash file system. See
http://www.linux-mtd.infradead.org/doc/ubifs.html
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Signed-off-by: Adrian Hunter <ext-adrian.hunter@nokia.com>
Diffstat (limited to 'fs/ubifs/dir.c')
-rw-r--r-- | fs/ubifs/dir.c | 1240 |
1 files changed, 1240 insertions, 0 deletions
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c new file mode 100644 index 000000000000..e90374be7d3b --- /dev/null +++ b/fs/ubifs/dir.c | |||
@@ -0,0 +1,1240 @@ | |||
1 | /* * This file is part of UBIFS. | ||
2 | * | ||
3 | * Copyright (C) 2006-2008 Nokia Corporation. | ||
4 | * Copyright (C) 2006, 2007 University of Szeged, Hungary | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License version 2 as published by | ||
8 | * the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along with | ||
16 | * this program; if not, write to the Free Software Foundation, Inc., 51 | ||
17 | * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | * | ||
19 | * Authors: Artem Bityutskiy (Битюцкий Артём) | ||
20 | * Adrian Hunter | ||
21 | * Zoltan Sogor | ||
22 | */ | ||
23 | |||
24 | /* | ||
25 | * This file implements directory operations. | ||
26 | * | ||
27 | * All FS operations in this file allocate budget before writing anything to the | ||
28 | * media. If they fail to allocate it, the error is returned. The only | ||
29 | * exceptions are 'ubifs_unlink()' and 'ubifs_rmdir()' which keep working even | ||
30 | * if they unable to allocate the budget, because deletion %-ENOSPC failure is | ||
31 | * not what users are usually ready to get. UBIFS budgeting subsystem has some | ||
32 | * space reserved for these purposes. | ||
33 | * | ||
34 | * All operations in this file write all inodes which they change straight | ||
35 | * away, instead of marking them dirty. For example, 'ubifs_link()' changes | ||
36 | * @i_size of the parent inode and writes the parent inode together with the | ||
37 | * target inode. This was done to simplify file-system recovery which would | ||
38 | * otherwise be very difficult to do. The only exception is rename which marks | ||
39 | * the re-named inode dirty (because its @i_ctime is updated) but does not | ||
40 | * write it, but just marks it as dirty. | ||
41 | */ | ||
42 | |||
43 | #include "ubifs.h" | ||
44 | |||
45 | /** | ||
46 | * inherit_flags - inherit flags of the parent inode. | ||
47 | * @dir: parent inode | ||
48 | * @mode: new inode mode flags | ||
49 | * | ||
50 | * This is a helper function for 'ubifs_new_inode()' which inherits flag of the | ||
51 | * parent directory inode @dir. UBIFS inodes inherit the following flags: | ||
52 | * o %UBIFS_COMPR_FL, which is useful to switch compression on/of on | ||
53 | * sub-directory basis; | ||
54 | * o %UBIFS_SYNC_FL - useful for the same reasons; | ||
55 | * o %UBIFS_DIRSYNC_FL - similar, but relevant only to directories. | ||
56 | * | ||
57 | * This function returns the inherited flags. | ||
58 | */ | ||
59 | static int inherit_flags(const struct inode *dir, int mode) | ||
60 | { | ||
61 | int flags; | ||
62 | const struct ubifs_inode *ui = ubifs_inode(dir); | ||
63 | |||
64 | if (!S_ISDIR(dir->i_mode)) | ||
65 | /* | ||
66 | * The parent is not a directory, which means that an extended | ||
67 | * attribute inode is being created. No flags. | ||
68 | */ | ||
69 | return 0; | ||
70 | |||
71 | flags = ui->flags & (UBIFS_COMPR_FL | UBIFS_SYNC_FL | UBIFS_DIRSYNC_FL); | ||
72 | if (!S_ISDIR(mode)) | ||
73 | /* The "DIRSYNC" flag only applies to directories */ | ||
74 | flags &= ~UBIFS_DIRSYNC_FL; | ||
75 | return flags; | ||
76 | } | ||
77 | |||
78 | /** | ||
79 | * ubifs_new_inode - allocate new UBIFS inode object. | ||
80 | * @c: UBIFS file-system description object | ||
81 | * @dir: parent directory inode | ||
82 | * @mode: inode mode flags | ||
83 | * | ||
84 | * This function finds an unused inode number, allocates new inode and | ||
85 | * initializes it. Returns new inode in case of success and an error code in | ||
86 | * case of failure. | ||
87 | */ | ||
88 | struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir, | ||
89 | int mode) | ||
90 | { | ||
91 | struct inode *inode; | ||
92 | struct ubifs_inode *ui; | ||
93 | |||
94 | inode = new_inode(c->vfs_sb); | ||
95 | ui = ubifs_inode(inode); | ||
96 | if (!inode) | ||
97 | return ERR_PTR(-ENOMEM); | ||
98 | |||
99 | /* | ||
100 | * Set 'S_NOCMTIME' to prevent VFS form updating [mc]time of inodes and | ||
101 | * marking them dirty in file write path (see 'file_update_time()'). | ||
102 | * UBIFS has to fully control "clean <-> dirty" transitions of inodes | ||
103 | * to make budgeting work. | ||
104 | */ | ||
105 | inode->i_flags |= (S_NOCMTIME); | ||
106 | |||
107 | inode->i_uid = current->fsuid; | ||
108 | if (dir->i_mode & S_ISGID) { | ||
109 | inode->i_gid = dir->i_gid; | ||
110 | if (S_ISDIR(mode)) | ||
111 | mode |= S_ISGID; | ||
112 | } else | ||
113 | inode->i_gid = current->fsgid; | ||
114 | inode->i_mode = mode; | ||
115 | inode->i_mtime = inode->i_atime = inode->i_ctime = | ||
116 | ubifs_current_time(inode); | ||
117 | inode->i_mapping->nrpages = 0; | ||
118 | /* Disable readahead */ | ||
119 | inode->i_mapping->backing_dev_info = &c->bdi; | ||
120 | |||
121 | switch (mode & S_IFMT) { | ||
122 | case S_IFREG: | ||
123 | inode->i_mapping->a_ops = &ubifs_file_address_operations; | ||
124 | inode->i_op = &ubifs_file_inode_operations; | ||
125 | inode->i_fop = &ubifs_file_operations; | ||
126 | break; | ||
127 | case S_IFDIR: | ||
128 | inode->i_op = &ubifs_dir_inode_operations; | ||
129 | inode->i_fop = &ubifs_dir_operations; | ||
130 | inode->i_size = ui->ui_size = UBIFS_INO_NODE_SZ; | ||
131 | break; | ||
132 | case S_IFLNK: | ||
133 | inode->i_op = &ubifs_symlink_inode_operations; | ||
134 | break; | ||
135 | case S_IFSOCK: | ||
136 | case S_IFIFO: | ||
137 | case S_IFBLK: | ||
138 | case S_IFCHR: | ||
139 | inode->i_op = &ubifs_file_inode_operations; | ||
140 | break; | ||
141 | default: | ||
142 | BUG(); | ||
143 | } | ||
144 | |||
145 | ui->flags = inherit_flags(dir, mode); | ||
146 | ubifs_set_inode_flags(inode); | ||
147 | if (S_ISREG(mode)) | ||
148 | ui->compr_type = c->default_compr; | ||
149 | else | ||
150 | ui->compr_type = UBIFS_COMPR_NONE; | ||
151 | ui->synced_i_size = 0; | ||
152 | |||
153 | spin_lock(&c->cnt_lock); | ||
154 | /* Inode number overflow is currently not supported */ | ||
155 | if (c->highest_inum >= INUM_WARN_WATERMARK) { | ||
156 | if (c->highest_inum >= INUM_WATERMARK) { | ||
157 | spin_unlock(&c->cnt_lock); | ||
158 | ubifs_err("out of inode numbers"); | ||
159 | make_bad_inode(inode); | ||
160 | iput(inode); | ||
161 | return ERR_PTR(-EINVAL); | ||
162 | } | ||
163 | ubifs_warn("running out of inode numbers (current %lu, max %d)", | ||
164 | c->highest_inum, INUM_WATERMARK); | ||
165 | } | ||
166 | |||
167 | inode->i_ino = ++c->highest_inum; | ||
168 | inode->i_generation = ++c->vfs_gen; | ||
169 | /* | ||
170 | * The creation sequence number remains with this inode for its | ||
171 | * lifetime. All nodes for this inode have a greater sequence number, | ||
172 | * and so it is possible to distinguish obsolete nodes belonging to a | ||
173 | * previous incarnation of the same inode number - for example, for the | ||
174 | * purpose of rebuilding the index. | ||
175 | */ | ||
176 | ui->creat_sqnum = ++c->max_sqnum; | ||
177 | spin_unlock(&c->cnt_lock); | ||
178 | return inode; | ||
179 | } | ||
180 | |||
181 | #ifdef CONFIG_UBIFS_FS_DEBUG | ||
182 | |||
183 | static int dbg_check_name(struct ubifs_dent_node *dent, struct qstr *nm) | ||
184 | { | ||
185 | if (!(ubifs_chk_flags & UBIFS_CHK_GEN)) | ||
186 | return 0; | ||
187 | if (le16_to_cpu(dent->nlen) != nm->len) | ||
188 | return -EINVAL; | ||
189 | if (memcmp(dent->name, nm->name, nm->len)) | ||
190 | return -EINVAL; | ||
191 | return 0; | ||
192 | } | ||
193 | |||
194 | #else | ||
195 | |||
196 | #define dbg_check_name(dent, nm) 0 | ||
197 | |||
198 | #endif | ||
199 | |||
200 | static struct dentry *ubifs_lookup(struct inode *dir, struct dentry *dentry, | ||
201 | struct nameidata *nd) | ||
202 | { | ||
203 | int err; | ||
204 | union ubifs_key key; | ||
205 | struct inode *inode = NULL; | ||
206 | struct ubifs_dent_node *dent; | ||
207 | struct ubifs_info *c = dir->i_sb->s_fs_info; | ||
208 | |||
209 | dbg_gen("'%.*s' in dir ino %lu", | ||
210 | dentry->d_name.len, dentry->d_name.name, dir->i_ino); | ||
211 | |||
212 | if (dentry->d_name.len > UBIFS_MAX_NLEN) | ||
213 | return ERR_PTR(-ENAMETOOLONG); | ||
214 | |||
215 | dent = kmalloc(UBIFS_MAX_DENT_NODE_SZ, GFP_NOFS); | ||
216 | if (!dent) | ||
217 | return ERR_PTR(-ENOMEM); | ||
218 | |||
219 | dent_key_init(c, &key, dir->i_ino, &dentry->d_name); | ||
220 | |||
221 | err = ubifs_tnc_lookup_nm(c, &key, dent, &dentry->d_name); | ||
222 | if (err) { | ||
223 | /* | ||
224 | * Do not hash the direntry if parent 'i_nlink' is zero, because | ||
225 | * this has side-effects - '->delete_inode()' call will not be | ||
226 | * called for the parent orphan inode, because 'd_count' of its | ||
227 | * direntry will stay 1 (it'll be negative direntry I guess) | ||
228 | * and prevent 'iput_final()' until the dentry is destroyed due | ||
229 | * to unmount or memory pressure. | ||
230 | */ | ||
231 | if (err == -ENOENT && dir->i_nlink != 0) { | ||
232 | dbg_gen("not found"); | ||
233 | goto done; | ||
234 | } | ||
235 | goto out; | ||
236 | } | ||
237 | |||
238 | if (dbg_check_name(dent, &dentry->d_name)) { | ||
239 | err = -EINVAL; | ||
240 | goto out; | ||
241 | } | ||
242 | |||
243 | inode = ubifs_iget(dir->i_sb, le64_to_cpu(dent->inum)); | ||
244 | if (IS_ERR(inode)) { | ||
245 | /* | ||
246 | * This should not happen. Probably the file-system needs | ||
247 | * checking. | ||
248 | */ | ||
249 | err = PTR_ERR(inode); | ||
250 | ubifs_err("dead directory entry '%.*s', error %d", | ||
251 | dentry->d_name.len, dentry->d_name.name, err); | ||
252 | ubifs_ro_mode(c, err); | ||
253 | goto out; | ||
254 | } | ||
255 | |||
256 | done: | ||
257 | kfree(dent); | ||
258 | /* | ||
259 | * Note, d_splice_alias() would be required instead if we supported | ||
260 | * NFS. | ||
261 | */ | ||
262 | d_add(dentry, inode); | ||
263 | return NULL; | ||
264 | |||
265 | out: | ||
266 | kfree(dent); | ||
267 | return ERR_PTR(err); | ||
268 | } | ||
269 | |||
270 | static int ubifs_create(struct inode *dir, struct dentry *dentry, int mode, | ||
271 | struct nameidata *nd) | ||
272 | { | ||
273 | struct inode *inode; | ||
274 | struct ubifs_info *c = dir->i_sb->s_fs_info; | ||
275 | int err, sz_change = CALC_DENT_SIZE(dentry->d_name.len); | ||
276 | struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1, | ||
277 | .dirtied_ino = 1 }; | ||
278 | struct ubifs_inode *dir_ui = ubifs_inode(dir); | ||
279 | |||
280 | /* | ||
281 | * Budget request settings: new inode, new direntry, changing the | ||
282 | * parent directory inode. | ||
283 | */ | ||
284 | |||
285 | dbg_gen("dent '%.*s', mode %#x in dir ino %lu", | ||
286 | dentry->d_name.len, dentry->d_name.name, mode, dir->i_ino); | ||
287 | |||
288 | err = ubifs_budget_space(c, &req); | ||
289 | if (err) | ||
290 | return err; | ||
291 | |||
292 | inode = ubifs_new_inode(c, dir, mode); | ||
293 | if (IS_ERR(inode)) { | ||
294 | err = PTR_ERR(inode); | ||
295 | goto out_budg; | ||
296 | } | ||
297 | |||
298 | mutex_lock(&dir_ui->ui_mutex); | ||
299 | dir->i_size += sz_change; | ||
300 | dir_ui->ui_size = dir->i_size; | ||
301 | dir->i_mtime = dir->i_ctime = inode->i_ctime; | ||
302 | err = ubifs_jnl_update(c, dir, &dentry->d_name, inode, 0, 0); | ||
303 | if (err) | ||
304 | goto out_cancel; | ||
305 | mutex_unlock(&dir_ui->ui_mutex); | ||
306 | |||
307 | ubifs_release_budget(c, &req); | ||
308 | insert_inode_hash(inode); | ||
309 | d_instantiate(dentry, inode); | ||
310 | return 0; | ||
311 | |||
312 | out_cancel: | ||
313 | dir->i_size -= sz_change; | ||
314 | dir_ui->ui_size = dir->i_size; | ||
315 | mutex_unlock(&dir_ui->ui_mutex); | ||
316 | make_bad_inode(inode); | ||
317 | iput(inode); | ||
318 | out_budg: | ||
319 | ubifs_release_budget(c, &req); | ||
320 | ubifs_err("cannot create regular file, error %d", err); | ||
321 | return err; | ||
322 | } | ||
323 | |||
324 | /** | ||
325 | * vfs_dent_type - get VFS directory entry type. | ||
326 | * @type: UBIFS directory entry type | ||
327 | * | ||
328 | * This function converts UBIFS directory entry type into VFS directory entry | ||
329 | * type. | ||
330 | */ | ||
331 | static unsigned int vfs_dent_type(uint8_t type) | ||
332 | { | ||
333 | switch (type) { | ||
334 | case UBIFS_ITYPE_REG: | ||
335 | return DT_REG; | ||
336 | case UBIFS_ITYPE_DIR: | ||
337 | return DT_DIR; | ||
338 | case UBIFS_ITYPE_LNK: | ||
339 | return DT_LNK; | ||
340 | case UBIFS_ITYPE_BLK: | ||
341 | return DT_BLK; | ||
342 | case UBIFS_ITYPE_CHR: | ||
343 | return DT_CHR; | ||
344 | case UBIFS_ITYPE_FIFO: | ||
345 | return DT_FIFO; | ||
346 | case UBIFS_ITYPE_SOCK: | ||
347 | return DT_SOCK; | ||
348 | default: | ||
349 | BUG(); | ||
350 | } | ||
351 | return 0; | ||
352 | } | ||
353 | |||
354 | /* | ||
355 | * The classical Unix view for directory is that it is a linear array of | ||
356 | * (name, inode number) entries. Linux/VFS assumes this model as well. | ||
357 | * Particularly, 'readdir()' call wants us to return a directory entry offset | ||
358 | * which later may be used to continue 'readdir()'ing the directory or to | ||
359 | * 'seek()' to that specific direntry. Obviously UBIFS does not really fit this | ||
360 | * model because directory entries are identified by keys, which may collide. | ||
361 | * | ||
362 | * UBIFS uses directory entry hash value for directory offsets, so | ||
363 | * 'seekdir()'/'telldir()' may not always work because of possible key | ||
364 | * collisions. But UBIFS guarantees that consecutive 'readdir()' calls work | ||
365 | * properly by means of saving full directory entry name in the private field | ||
366 | * of the file description object. | ||
367 | * | ||
368 | * This means that UBIFS cannot support NFS which requires full | ||
369 | * 'seekdir()'/'telldir()' support. | ||
370 | */ | ||
371 | static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir) | ||
372 | { | ||
373 | int err, over = 0; | ||
374 | struct qstr nm; | ||
375 | union ubifs_key key; | ||
376 | struct ubifs_dent_node *dent; | ||
377 | struct inode *dir = file->f_path.dentry->d_inode; | ||
378 | struct ubifs_info *c = dir->i_sb->s_fs_info; | ||
379 | |||
380 | dbg_gen("dir ino %lu, f_pos %#llx", dir->i_ino, file->f_pos); | ||
381 | |||
382 | if (file->f_pos > UBIFS_S_KEY_HASH_MASK || file->f_pos == 2) | ||
383 | /* | ||
384 | * The directory was seek'ed to a senseless position or there | ||
385 | * are no more entries. | ||
386 | */ | ||
387 | return 0; | ||
388 | |||
389 | /* File positions 0 and 1 correspond to "." and ".." */ | ||
390 | if (file->f_pos == 0) { | ||
391 | ubifs_assert(!file->private_data); | ||
392 | over = filldir(dirent, ".", 1, 0, dir->i_ino, DT_DIR); | ||
393 | if (over) | ||
394 | return 0; | ||
395 | file->f_pos = 1; | ||
396 | } | ||
397 | |||
398 | if (file->f_pos == 1) { | ||
399 | ubifs_assert(!file->private_data); | ||
400 | over = filldir(dirent, "..", 2, 1, | ||
401 | parent_ino(file->f_path.dentry), DT_DIR); | ||
402 | if (over) | ||
403 | return 0; | ||
404 | |||
405 | /* Find the first entry in TNC and save it */ | ||
406 | lowest_dent_key(c, &key, dir->i_ino); | ||
407 | nm.name = NULL; | ||
408 | dent = ubifs_tnc_next_ent(c, &key, &nm); | ||
409 | if (IS_ERR(dent)) { | ||
410 | err = PTR_ERR(dent); | ||
411 | goto out; | ||
412 | } | ||
413 | |||
414 | file->f_pos = key_hash_flash(c, &dent->key); | ||
415 | file->private_data = dent; | ||
416 | } | ||
417 | |||
418 | dent = file->private_data; | ||
419 | if (!dent) { | ||
420 | /* | ||
421 | * The directory was seek'ed to and is now readdir'ed. | ||
422 | * Find the entry corresponding to @file->f_pos or the | ||
423 | * closest one. | ||
424 | */ | ||
425 | dent_key_init_hash(c, &key, dir->i_ino, file->f_pos); | ||
426 | nm.name = NULL; | ||
427 | dent = ubifs_tnc_next_ent(c, &key, &nm); | ||
428 | if (IS_ERR(dent)) { | ||
429 | err = PTR_ERR(dent); | ||
430 | goto out; | ||
431 | } | ||
432 | file->f_pos = key_hash_flash(c, &dent->key); | ||
433 | file->private_data = dent; | ||
434 | } | ||
435 | |||
436 | while (1) { | ||
437 | dbg_gen("feed '%s', ino %llu, new f_pos %#x", | ||
438 | dent->name, le64_to_cpu(dent->inum), | ||
439 | key_hash_flash(c, &dent->key)); | ||
440 | ubifs_assert(dent->ch.sqnum > ubifs_inode(dir)->creat_sqnum); | ||
441 | |||
442 | nm.len = le16_to_cpu(dent->nlen); | ||
443 | over = filldir(dirent, dent->name, nm.len, file->f_pos, | ||
444 | le64_to_cpu(dent->inum), | ||
445 | vfs_dent_type(dent->type)); | ||
446 | if (over) | ||
447 | return 0; | ||
448 | |||
449 | /* Switch to the next entry */ | ||
450 | key_read(c, &dent->key, &key); | ||
451 | nm.name = dent->name; | ||
452 | dent = ubifs_tnc_next_ent(c, &key, &nm); | ||
453 | if (IS_ERR(dent)) { | ||
454 | err = PTR_ERR(dent); | ||
455 | goto out; | ||
456 | } | ||
457 | |||
458 | kfree(file->private_data); | ||
459 | file->f_pos = key_hash_flash(c, &dent->key); | ||
460 | file->private_data = dent; | ||
461 | cond_resched(); | ||
462 | } | ||
463 | |||
464 | out: | ||
465 | if (err != -ENOENT) { | ||
466 | ubifs_err("cannot find next direntry, error %d", err); | ||
467 | return err; | ||
468 | } | ||
469 | |||
470 | kfree(file->private_data); | ||
471 | file->private_data = NULL; | ||
472 | file->f_pos = 2; | ||
473 | return 0; | ||
474 | } | ||
475 | |||
476 | /* If a directory is seeked, we have to free saved readdir() state */ | ||
477 | static loff_t ubifs_dir_llseek(struct file *file, loff_t offset, int origin) | ||
478 | { | ||
479 | kfree(file->private_data); | ||
480 | file->private_data = NULL; | ||
481 | return generic_file_llseek(file, offset, origin); | ||
482 | } | ||
483 | |||
484 | /* Free saved readdir() state when the directory is closed */ | ||
485 | static int ubifs_dir_release(struct inode *dir, struct file *file) | ||
486 | { | ||
487 | kfree(file->private_data); | ||
488 | file->private_data = NULL; | ||
489 | return 0; | ||
490 | } | ||
491 | |||
492 | /** | ||
493 | * lock_2_inodes - lock two UBIFS inodes. | ||
494 | * @inode1: first inode | ||
495 | * @inode2: second inode | ||
496 | */ | ||
497 | static void lock_2_inodes(struct inode *inode1, struct inode *inode2) | ||
498 | { | ||
499 | if (inode1->i_ino < inode2->i_ino) { | ||
500 | mutex_lock_nested(&ubifs_inode(inode1)->ui_mutex, WB_MUTEX_2); | ||
501 | mutex_lock_nested(&ubifs_inode(inode2)->ui_mutex, WB_MUTEX_3); | ||
502 | } else { | ||
503 | mutex_lock_nested(&ubifs_inode(inode2)->ui_mutex, WB_MUTEX_2); | ||
504 | mutex_lock_nested(&ubifs_inode(inode1)->ui_mutex, WB_MUTEX_3); | ||
505 | } | ||
506 | } | ||
507 | |||
508 | /** | ||
509 | * unlock_2_inodes - unlock two UBIFS inodes inodes. | ||
510 | * @inode1: first inode | ||
511 | * @inode2: second inode | ||
512 | */ | ||
513 | static void unlock_2_inodes(struct inode *inode1, struct inode *inode2) | ||
514 | { | ||
515 | mutex_unlock(&ubifs_inode(inode1)->ui_mutex); | ||
516 | mutex_unlock(&ubifs_inode(inode2)->ui_mutex); | ||
517 | } | ||
518 | |||
519 | static int ubifs_link(struct dentry *old_dentry, struct inode *dir, | ||
520 | struct dentry *dentry) | ||
521 | { | ||
522 | struct ubifs_info *c = dir->i_sb->s_fs_info; | ||
523 | struct inode *inode = old_dentry->d_inode; | ||
524 | struct ubifs_inode *ui = ubifs_inode(inode); | ||
525 | struct ubifs_inode *dir_ui = ubifs_inode(dir); | ||
526 | int err, sz_change = CALC_DENT_SIZE(dentry->d_name.len); | ||
527 | struct ubifs_budget_req req = { .new_dent = 1, .dirtied_ino = 2, | ||
528 | .dirtied_ino_d = ui->data_len }; | ||
529 | |||
530 | /* | ||
531 | * Budget request settings: new direntry, changing the target inode, | ||
532 | * changing the parent inode. | ||
533 | */ | ||
534 | |||
535 | dbg_gen("dent '%.*s' to ino %lu (nlink %d) in dir ino %lu", | ||
536 | dentry->d_name.len, dentry->d_name.name, inode->i_ino, | ||
537 | inode->i_nlink, dir->i_ino); | ||
538 | err = dbg_check_synced_i_size(inode); | ||
539 | if (err) | ||
540 | return err; | ||
541 | |||
542 | err = ubifs_budget_space(c, &req); | ||
543 | if (err) | ||
544 | return err; | ||
545 | |||
546 | lock_2_inodes(dir, inode); | ||
547 | inc_nlink(inode); | ||
548 | atomic_inc(&inode->i_count); | ||
549 | inode->i_ctime = ubifs_current_time(inode); | ||
550 | dir->i_size += sz_change; | ||
551 | dir_ui->ui_size = dir->i_size; | ||
552 | dir->i_mtime = dir->i_ctime = inode->i_ctime; | ||
553 | err = ubifs_jnl_update(c, dir, &dentry->d_name, inode, 0, 0); | ||
554 | if (err) | ||
555 | goto out_cancel; | ||
556 | unlock_2_inodes(dir, inode); | ||
557 | |||
558 | ubifs_release_budget(c, &req); | ||
559 | d_instantiate(dentry, inode); | ||
560 | return 0; | ||
561 | |||
562 | out_cancel: | ||
563 | dir->i_size -= sz_change; | ||
564 | dir_ui->ui_size = dir->i_size; | ||
565 | drop_nlink(inode); | ||
566 | unlock_2_inodes(dir, inode); | ||
567 | ubifs_release_budget(c, &req); | ||
568 | iput(inode); | ||
569 | return err; | ||
570 | } | ||
571 | |||
572 | static int ubifs_unlink(struct inode *dir, struct dentry *dentry) | ||
573 | { | ||
574 | struct ubifs_info *c = dir->i_sb->s_fs_info; | ||
575 | struct inode *inode = dentry->d_inode; | ||
576 | struct ubifs_inode *dir_ui = ubifs_inode(dir); | ||
577 | int sz_change = CALC_DENT_SIZE(dentry->d_name.len); | ||
578 | int err, budgeted = 1; | ||
579 | struct ubifs_budget_req req = { .mod_dent = 1, .dirtied_ino = 2 }; | ||
580 | |||
581 | /* | ||
582 | * Budget request settings: deletion direntry, deletion inode (+1 for | ||
583 | * @dirtied_ino), changing the parent directory inode. If budgeting | ||
584 | * fails, go ahead anyway because we have extra space reserved for | ||
585 | * deletions. | ||
586 | */ | ||
587 | |||
588 | dbg_gen("dent '%.*s' from ino %lu (nlink %d) in dir ino %lu", | ||
589 | dentry->d_name.len, dentry->d_name.name, inode->i_ino, | ||
590 | inode->i_nlink, dir->i_ino); | ||
591 | err = dbg_check_synced_i_size(inode); | ||
592 | if (err) | ||
593 | return err; | ||
594 | |||
595 | err = ubifs_budget_space(c, &req); | ||
596 | if (err) { | ||
597 | if (err != -ENOSPC) | ||
598 | return err; | ||
599 | err = 0; | ||
600 | budgeted = 0; | ||
601 | } | ||
602 | |||
603 | lock_2_inodes(dir, inode); | ||
604 | inode->i_ctime = ubifs_current_time(dir); | ||
605 | drop_nlink(inode); | ||
606 | dir->i_size -= sz_change; | ||
607 | dir_ui->ui_size = dir->i_size; | ||
608 | dir->i_mtime = dir->i_ctime = inode->i_ctime; | ||
609 | err = ubifs_jnl_update(c, dir, &dentry->d_name, inode, 1, 0); | ||
610 | if (err) | ||
611 | goto out_cancel; | ||
612 | unlock_2_inodes(dir, inode); | ||
613 | |||
614 | if (budgeted) | ||
615 | ubifs_release_budget(c, &req); | ||
616 | else { | ||
617 | /* We've deleted something - clean the "no space" flags */ | ||
618 | c->nospace = c->nospace_rp = 0; | ||
619 | smp_wmb(); | ||
620 | } | ||
621 | return 0; | ||
622 | |||
623 | out_cancel: | ||
624 | dir->i_size += sz_change; | ||
625 | dir_ui->ui_size = dir->i_size; | ||
626 | inc_nlink(inode); | ||
627 | unlock_2_inodes(dir, inode); | ||
628 | if (budgeted) | ||
629 | ubifs_release_budget(c, &req); | ||
630 | return err; | ||
631 | } | ||
632 | |||
633 | /** | ||
634 | * check_dir_empty - check if a directory is empty or not. | ||
635 | * @c: UBIFS file-system description object | ||
636 | * @dir: VFS inode object of the directory to check | ||
637 | * | ||
638 | * This function checks if directory @dir is empty. Returns zero if the | ||
639 | * directory is empty, %-ENOTEMPTY if it is not, and other negative error codes | ||
640 | * in case of of errors. | ||
641 | */ | ||
642 | static int check_dir_empty(struct ubifs_info *c, struct inode *dir) | ||
643 | { | ||
644 | struct qstr nm = { .name = NULL }; | ||
645 | struct ubifs_dent_node *dent; | ||
646 | union ubifs_key key; | ||
647 | int err; | ||
648 | |||
649 | lowest_dent_key(c, &key, dir->i_ino); | ||
650 | dent = ubifs_tnc_next_ent(c, &key, &nm); | ||
651 | if (IS_ERR(dent)) { | ||
652 | err = PTR_ERR(dent); | ||
653 | if (err == -ENOENT) | ||
654 | err = 0; | ||
655 | } else { | ||
656 | kfree(dent); | ||
657 | err = -ENOTEMPTY; | ||
658 | } | ||
659 | return err; | ||
660 | } | ||
661 | |||
662 | static int ubifs_rmdir(struct inode *dir, struct dentry *dentry) | ||
663 | { | ||
664 | struct ubifs_info *c = dir->i_sb->s_fs_info; | ||
665 | struct inode *inode = dentry->d_inode; | ||
666 | int sz_change = CALC_DENT_SIZE(dentry->d_name.len); | ||
667 | int err, budgeted = 1; | ||
668 | struct ubifs_inode *dir_ui = ubifs_inode(dir); | ||
669 | struct ubifs_budget_req req = { .mod_dent = 1, .dirtied_ino = 2 }; | ||
670 | |||
671 | /* | ||
672 | * Budget request settings: deletion direntry, deletion inode and | ||
673 | * changing the parent inode. If budgeting fails, go ahead anyway | ||
674 | * because we have extra space reserved for deletions. | ||
675 | */ | ||
676 | |||
677 | dbg_gen("directory '%.*s', ino %lu in dir ino %lu", dentry->d_name.len, | ||
678 | dentry->d_name.name, inode->i_ino, dir->i_ino); | ||
679 | |||
680 | err = check_dir_empty(c, dentry->d_inode); | ||
681 | if (err) | ||
682 | return err; | ||
683 | |||
684 | err = ubifs_budget_space(c, &req); | ||
685 | if (err) { | ||
686 | if (err != -ENOSPC) | ||
687 | return err; | ||
688 | budgeted = 0; | ||
689 | } | ||
690 | |||
691 | lock_2_inodes(dir, inode); | ||
692 | inode->i_ctime = ubifs_current_time(dir); | ||
693 | clear_nlink(inode); | ||
694 | drop_nlink(dir); | ||
695 | dir->i_size -= sz_change; | ||
696 | dir_ui->ui_size = dir->i_size; | ||
697 | dir->i_mtime = dir->i_ctime = inode->i_ctime; | ||
698 | err = ubifs_jnl_update(c, dir, &dentry->d_name, inode, 1, 0); | ||
699 | if (err) | ||
700 | goto out_cancel; | ||
701 | unlock_2_inodes(dir, inode); | ||
702 | |||
703 | if (budgeted) | ||
704 | ubifs_release_budget(c, &req); | ||
705 | else { | ||
706 | /* We've deleted something - clean the "no space" flags */ | ||
707 | c->nospace = c->nospace_rp = 0; | ||
708 | smp_wmb(); | ||
709 | } | ||
710 | return 0; | ||
711 | |||
712 | out_cancel: | ||
713 | dir->i_size += sz_change; | ||
714 | dir_ui->ui_size = dir->i_size; | ||
715 | inc_nlink(dir); | ||
716 | inc_nlink(inode); | ||
717 | inc_nlink(inode); | ||
718 | unlock_2_inodes(dir, inode); | ||
719 | if (budgeted) | ||
720 | ubifs_release_budget(c, &req); | ||
721 | return err; | ||
722 | } | ||
723 | |||
724 | static int ubifs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | ||
725 | { | ||
726 | struct inode *inode; | ||
727 | struct ubifs_inode *dir_ui = ubifs_inode(dir); | ||
728 | struct ubifs_info *c = dir->i_sb->s_fs_info; | ||
729 | int err, sz_change = CALC_DENT_SIZE(dentry->d_name.len); | ||
730 | struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1, | ||
731 | .dirtied_ino_d = 1 }; | ||
732 | |||
733 | /* | ||
734 | * Budget request settings: new inode, new direntry and changing parent | ||
735 | * directory inode. | ||
736 | */ | ||
737 | |||
738 | dbg_gen("dent '%.*s', mode %#x in dir ino %lu", | ||
739 | dentry->d_name.len, dentry->d_name.name, mode, dir->i_ino); | ||
740 | |||
741 | err = ubifs_budget_space(c, &req); | ||
742 | if (err) | ||
743 | return err; | ||
744 | |||
745 | inode = ubifs_new_inode(c, dir, S_IFDIR | mode); | ||
746 | if (IS_ERR(inode)) { | ||
747 | err = PTR_ERR(inode); | ||
748 | goto out_budg; | ||
749 | } | ||
750 | |||
751 | mutex_lock(&dir_ui->ui_mutex); | ||
752 | insert_inode_hash(inode); | ||
753 | inc_nlink(inode); | ||
754 | inc_nlink(dir); | ||
755 | dir->i_size += sz_change; | ||
756 | dir_ui->ui_size = dir->i_size; | ||
757 | dir->i_mtime = dir->i_ctime = inode->i_ctime; | ||
758 | err = ubifs_jnl_update(c, dir, &dentry->d_name, inode, 0, 0); | ||
759 | if (err) { | ||
760 | ubifs_err("cannot create directory, error %d", err); | ||
761 | goto out_cancel; | ||
762 | } | ||
763 | mutex_unlock(&dir_ui->ui_mutex); | ||
764 | |||
765 | ubifs_release_budget(c, &req); | ||
766 | d_instantiate(dentry, inode); | ||
767 | return 0; | ||
768 | |||
769 | out_cancel: | ||
770 | dir->i_size -= sz_change; | ||
771 | dir_ui->ui_size = dir->i_size; | ||
772 | drop_nlink(dir); | ||
773 | mutex_unlock(&dir_ui->ui_mutex); | ||
774 | make_bad_inode(inode); | ||
775 | iput(inode); | ||
776 | out_budg: | ||
777 | ubifs_release_budget(c, &req); | ||
778 | return err; | ||
779 | } | ||
780 | |||
781 | static int ubifs_mknod(struct inode *dir, struct dentry *dentry, | ||
782 | int mode, dev_t rdev) | ||
783 | { | ||
784 | struct inode *inode; | ||
785 | struct ubifs_inode *ui; | ||
786 | struct ubifs_inode *dir_ui = ubifs_inode(dir); | ||
787 | struct ubifs_info *c = dir->i_sb->s_fs_info; | ||
788 | union ubifs_dev_desc *dev = NULL; | ||
789 | int sz_change = CALC_DENT_SIZE(dentry->d_name.len); | ||
790 | int err, devlen = 0; | ||
791 | struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1, | ||
792 | .new_ino_d = devlen, .dirtied_ino = 1 }; | ||
793 | |||
794 | /* | ||
795 | * Budget request settings: new inode, new direntry and changing parent | ||
796 | * directory inode. | ||
797 | */ | ||
798 | |||
799 | dbg_gen("dent '%.*s' in dir ino %lu", | ||
800 | dentry->d_name.len, dentry->d_name.name, dir->i_ino); | ||
801 | |||
802 | if (!new_valid_dev(rdev)) | ||
803 | return -EINVAL; | ||
804 | |||
805 | if (S_ISBLK(mode) || S_ISCHR(mode)) { | ||
806 | dev = kmalloc(sizeof(union ubifs_dev_desc), GFP_NOFS); | ||
807 | if (!dev) | ||
808 | return -ENOMEM; | ||
809 | devlen = ubifs_encode_dev(dev, rdev); | ||
810 | } | ||
811 | |||
812 | err = ubifs_budget_space(c, &req); | ||
813 | if (err) { | ||
814 | kfree(dev); | ||
815 | return err; | ||
816 | } | ||
817 | |||
818 | inode = ubifs_new_inode(c, dir, mode); | ||
819 | if (IS_ERR(inode)) { | ||
820 | kfree(dev); | ||
821 | err = PTR_ERR(inode); | ||
822 | goto out_budg; | ||
823 | } | ||
824 | |||
825 | init_special_inode(inode, inode->i_mode, rdev); | ||
826 | inode->i_size = ubifs_inode(inode)->ui_size = devlen; | ||
827 | ui = ubifs_inode(inode); | ||
828 | ui->data = dev; | ||
829 | ui->data_len = devlen; | ||
830 | |||
831 | mutex_lock(&dir_ui->ui_mutex); | ||
832 | dir->i_size += sz_change; | ||
833 | dir_ui->ui_size = dir->i_size; | ||
834 | dir->i_mtime = dir->i_ctime = inode->i_ctime; | ||
835 | err = ubifs_jnl_update(c, dir, &dentry->d_name, inode, 0, 0); | ||
836 | if (err) | ||
837 | goto out_cancel; | ||
838 | mutex_unlock(&dir_ui->ui_mutex); | ||
839 | |||
840 | ubifs_release_budget(c, &req); | ||
841 | insert_inode_hash(inode); | ||
842 | d_instantiate(dentry, inode); | ||
843 | return 0; | ||
844 | |||
845 | out_cancel: | ||
846 | dir->i_size -= sz_change; | ||
847 | dir_ui->ui_size = dir->i_size; | ||
848 | mutex_unlock(&dir_ui->ui_mutex); | ||
849 | make_bad_inode(inode); | ||
850 | iput(inode); | ||
851 | out_budg: | ||
852 | ubifs_release_budget(c, &req); | ||
853 | return err; | ||
854 | } | ||
855 | |||
856 | static int ubifs_symlink(struct inode *dir, struct dentry *dentry, | ||
857 | const char *symname) | ||
858 | { | ||
859 | struct inode *inode; | ||
860 | struct ubifs_inode *ui; | ||
861 | struct ubifs_inode *dir_ui = ubifs_inode(dir); | ||
862 | struct ubifs_info *c = dir->i_sb->s_fs_info; | ||
863 | int err, len = strlen(symname); | ||
864 | int sz_change = CALC_DENT_SIZE(dentry->d_name.len); | ||
865 | struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1, | ||
866 | .new_ino_d = len, .dirtied_ino = 1 }; | ||
867 | |||
868 | /* | ||
869 | * Budget request settings: new inode, new direntry and changing parent | ||
870 | * directory inode. | ||
871 | */ | ||
872 | |||
873 | dbg_gen("dent '%.*s', target '%s' in dir ino %lu", dentry->d_name.len, | ||
874 | dentry->d_name.name, symname, dir->i_ino); | ||
875 | |||
876 | if (len > UBIFS_MAX_INO_DATA) | ||
877 | return -ENAMETOOLONG; | ||
878 | |||
879 | err = ubifs_budget_space(c, &req); | ||
880 | if (err) | ||
881 | return err; | ||
882 | |||
883 | inode = ubifs_new_inode(c, dir, S_IFLNK | S_IRWXUGO); | ||
884 | if (IS_ERR(inode)) { | ||
885 | err = PTR_ERR(inode); | ||
886 | goto out_budg; | ||
887 | } | ||
888 | |||
889 | ui = ubifs_inode(inode); | ||
890 | ui->data = kmalloc(len + 1, GFP_NOFS); | ||
891 | if (!ui->data) { | ||
892 | err = -ENOMEM; | ||
893 | goto out_inode; | ||
894 | } | ||
895 | |||
896 | memcpy(ui->data, symname, len); | ||
897 | ((char *)ui->data)[len] = '\0'; | ||
898 | /* | ||
899 | * The terminating zero byte is not written to the flash media and it | ||
900 | * is put just to make later in-memory string processing simpler. Thus, | ||
901 | * data length is @len, not @len + %1. | ||
902 | */ | ||
903 | ui->data_len = len; | ||
904 | inode->i_size = ubifs_inode(inode)->ui_size = len; | ||
905 | |||
906 | mutex_lock(&dir_ui->ui_mutex); | ||
907 | dir->i_size += sz_change; | ||
908 | dir_ui->ui_size = dir->i_size; | ||
909 | dir->i_mtime = dir->i_ctime = inode->i_ctime; | ||
910 | err = ubifs_jnl_update(c, dir, &dentry->d_name, inode, 0, 0); | ||
911 | if (err) | ||
912 | goto out_cancel; | ||
913 | mutex_unlock(&dir_ui->ui_mutex); | ||
914 | |||
915 | ubifs_release_budget(c, &req); | ||
916 | insert_inode_hash(inode); | ||
917 | d_instantiate(dentry, inode); | ||
918 | return 0; | ||
919 | |||
920 | out_cancel: | ||
921 | dir->i_size -= sz_change; | ||
922 | dir_ui->ui_size = dir->i_size; | ||
923 | mutex_unlock(&dir_ui->ui_mutex); | ||
924 | out_inode: | ||
925 | make_bad_inode(inode); | ||
926 | iput(inode); | ||
927 | out_budg: | ||
928 | ubifs_release_budget(c, &req); | ||
929 | return err; | ||
930 | } | ||
931 | |||
932 | /** | ||
933 | * lock_3_inodes - lock three UBIFS inodes for rename. | ||
934 | * @inode1: first inode | ||
935 | * @inode2: second inode | ||
936 | * @inode3: third inode | ||
937 | * | ||
938 | * For 'ubifs_rename()', @inode1 may be the same as @inode2 whereas @inode3 may | ||
939 | * be null. | ||
940 | */ | ||
941 | static void lock_3_inodes(struct inode *inode1, struct inode *inode2, | ||
942 | struct inode *inode3) | ||
943 | { | ||
944 | struct inode *i1, *i2, *i3; | ||
945 | |||
946 | if (!inode3) { | ||
947 | if (inode1 != inode2) { | ||
948 | lock_2_inodes(inode1, inode2); | ||
949 | return; | ||
950 | } | ||
951 | mutex_lock_nested(&ubifs_inode(inode1)->ui_mutex, WB_MUTEX_1); | ||
952 | return; | ||
953 | } | ||
954 | |||
955 | if (inode1 == inode2) { | ||
956 | lock_2_inodes(inode1, inode3); | ||
957 | return; | ||
958 | } | ||
959 | |||
960 | /* 3 different inodes */ | ||
961 | if (inode1 < inode2) { | ||
962 | i3 = inode2; | ||
963 | if (inode1 < inode3) { | ||
964 | i1 = inode1; | ||
965 | i2 = inode3; | ||
966 | } else { | ||
967 | i1 = inode3; | ||
968 | i2 = inode1; | ||
969 | } | ||
970 | } else { | ||
971 | i3 = inode1; | ||
972 | if (inode2 < inode3) { | ||
973 | i1 = inode2; | ||
974 | i2 = inode3; | ||
975 | } else { | ||
976 | i1 = inode3; | ||
977 | i2 = inode2; | ||
978 | } | ||
979 | } | ||
980 | mutex_lock_nested(&ubifs_inode(i1)->ui_mutex, WB_MUTEX_1); | ||
981 | lock_2_inodes(i2, i3); | ||
982 | } | ||
983 | |||
984 | /** | ||
985 | * unlock_3_inodes - unlock three UBIFS inodes for rename. | ||
986 | * @inode1: first inode | ||
987 | * @inode2: second inode | ||
988 | * @inode3: third inode | ||
989 | */ | ||
990 | static void unlock_3_inodes(struct inode *inode1, struct inode *inode2, | ||
991 | struct inode *inode3) | ||
992 | { | ||
993 | mutex_unlock(&ubifs_inode(inode1)->ui_mutex); | ||
994 | if (inode1 != inode2) | ||
995 | mutex_unlock(&ubifs_inode(inode2)->ui_mutex); | ||
996 | if (inode3) | ||
997 | mutex_unlock(&ubifs_inode(inode3)->ui_mutex); | ||
998 | } | ||
999 | |||
1000 | static int ubifs_rename(struct inode *old_dir, struct dentry *old_dentry, | ||
1001 | struct inode *new_dir, struct dentry *new_dentry) | ||
1002 | { | ||
1003 | struct ubifs_info *c = old_dir->i_sb->s_fs_info; | ||
1004 | struct inode *old_inode = old_dentry->d_inode; | ||
1005 | struct inode *new_inode = new_dentry->d_inode; | ||
1006 | struct ubifs_inode *old_inode_ui = ubifs_inode(old_inode); | ||
1007 | int err, release, sync = 0, move = (new_dir != old_dir); | ||
1008 | int is_dir = S_ISDIR(old_inode->i_mode); | ||
1009 | int unlink = !!new_inode; | ||
1010 | int new_sz = CALC_DENT_SIZE(new_dentry->d_name.len); | ||
1011 | int old_sz = CALC_DENT_SIZE(old_dentry->d_name.len); | ||
1012 | struct ubifs_budget_req req = { .new_dent = 1, .mod_dent = 1, | ||
1013 | .dirtied_ino = 3 }; | ||
1014 | struct ubifs_budget_req ino_req = { .dirtied_ino = 1, | ||
1015 | .dirtied_ino_d = old_inode_ui->data_len }; | ||
1016 | struct timespec time; | ||
1017 | |||
1018 | /* | ||
1019 | * Budget request settings: deletion direntry, new direntry, removing | ||
1020 | * the old inode, and changing old and new parent directory inodes. | ||
1021 | * | ||
1022 | * However, this operation also marks the target inode as dirty and | ||
1023 | * does not write it, so we allocate budget for the target inode | ||
1024 | * separately. | ||
1025 | */ | ||
1026 | |||
1027 | dbg_gen("dent '%.*s' ino %lu in dir ino %lu to dent '%.*s' in " | ||
1028 | "dir ino %lu", old_dentry->d_name.len, old_dentry->d_name.name, | ||
1029 | old_inode->i_ino, old_dir->i_ino, new_dentry->d_name.len, | ||
1030 | new_dentry->d_name.name, new_dir->i_ino); | ||
1031 | |||
1032 | if (unlink && is_dir) { | ||
1033 | err = check_dir_empty(c, new_inode); | ||
1034 | if (err) | ||
1035 | return err; | ||
1036 | } | ||
1037 | |||
1038 | err = ubifs_budget_space(c, &req); | ||
1039 | if (err) | ||
1040 | return err; | ||
1041 | err = ubifs_budget_space(c, &ino_req); | ||
1042 | if (err) { | ||
1043 | ubifs_release_budget(c, &req); | ||
1044 | return err; | ||
1045 | } | ||
1046 | |||
1047 | lock_3_inodes(old_dir, new_dir, new_inode); | ||
1048 | |||
1049 | /* | ||
1050 | * Like most other Unix systems, set the @i_ctime for inodes on a | ||
1051 | * rename. | ||
1052 | */ | ||
1053 | time = ubifs_current_time(old_dir); | ||
1054 | old_inode->i_ctime = time; | ||
1055 | |||
1056 | /* We must adjust parent link count when renaming directories */ | ||
1057 | if (is_dir) { | ||
1058 | if (move) { | ||
1059 | /* | ||
1060 | * @old_dir loses a link because we are moving | ||
1061 | * @old_inode to a different directory. | ||
1062 | */ | ||
1063 | drop_nlink(old_dir); | ||
1064 | /* | ||
1065 | * @new_dir only gains a link if we are not also | ||
1066 | * overwriting an existing directory. | ||
1067 | */ | ||
1068 | if (!unlink) | ||
1069 | inc_nlink(new_dir); | ||
1070 | } else { | ||
1071 | /* | ||
1072 | * @old_inode is not moving to a different directory, | ||
1073 | * but @old_dir still loses a link if we are | ||
1074 | * overwriting an existing directory. | ||
1075 | */ | ||
1076 | if (unlink) | ||
1077 | drop_nlink(old_dir); | ||
1078 | } | ||
1079 | } | ||
1080 | |||
1081 | old_dir->i_size -= old_sz; | ||
1082 | ubifs_inode(old_dir)->ui_size = old_dir->i_size; | ||
1083 | old_dir->i_mtime = old_dir->i_ctime = time; | ||
1084 | new_dir->i_mtime = new_dir->i_ctime = time; | ||
1085 | |||
1086 | /* | ||
1087 | * And finally, if we unlinked a direntry which happened to have the | ||
1088 | * same name as the moved direntry, we have to decrement @i_nlink of | ||
1089 | * the unlinked inode and change its ctime. | ||
1090 | */ | ||
1091 | if (unlink) { | ||
1092 | /* | ||
1093 | * Directories cannot have hard-links, so if this is a | ||
1094 | * directory, decrement its @i_nlink twice because an empty | ||
1095 | * directory has @i_nlink 2. | ||
1096 | */ | ||
1097 | if (is_dir) | ||
1098 | drop_nlink(new_inode); | ||
1099 | new_inode->i_ctime = time; | ||
1100 | drop_nlink(new_inode); | ||
1101 | } else { | ||
1102 | new_dir->i_size += new_sz; | ||
1103 | ubifs_inode(new_dir)->ui_size = new_dir->i_size; | ||
1104 | } | ||
1105 | |||
1106 | /* | ||
1107 | * Do not ask 'ubifs_jnl_rename()' to flush write-buffer if @old_inode | ||
1108 | * is dirty, because this will be done later on at the end of | ||
1109 | * 'ubifs_rename()'. | ||
1110 | */ | ||
1111 | if (IS_SYNC(old_inode)) { | ||
1112 | sync = IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir); | ||
1113 | if (unlink && IS_SYNC(new_inode)) | ||
1114 | sync = 1; | ||
1115 | } | ||
1116 | err = ubifs_jnl_rename(c, old_dir, old_dentry, new_dir, new_dentry, | ||
1117 | sync); | ||
1118 | if (err) | ||
1119 | goto out_cancel; | ||
1120 | |||
1121 | unlock_3_inodes(old_dir, new_dir, new_inode); | ||
1122 | ubifs_release_budget(c, &req); | ||
1123 | |||
1124 | mutex_lock(&old_inode_ui->ui_mutex); | ||
1125 | release = old_inode_ui->dirty; | ||
1126 | mark_inode_dirty_sync(old_inode); | ||
1127 | mutex_unlock(&old_inode_ui->ui_mutex); | ||
1128 | |||
1129 | if (release) | ||
1130 | ubifs_release_budget(c, &ino_req); | ||
1131 | if (IS_SYNC(old_inode)) | ||
1132 | err = old_inode->i_sb->s_op->write_inode(old_inode, 1); | ||
1133 | return err; | ||
1134 | |||
1135 | out_cancel: | ||
1136 | if (unlink) { | ||
1137 | if (is_dir) | ||
1138 | inc_nlink(new_inode); | ||
1139 | inc_nlink(new_inode); | ||
1140 | } else { | ||
1141 | new_dir->i_size -= new_sz; | ||
1142 | ubifs_inode(new_dir)->ui_size = new_dir->i_size; | ||
1143 | } | ||
1144 | old_dir->i_size += old_sz; | ||
1145 | ubifs_inode(old_dir)->ui_size = old_dir->i_size; | ||
1146 | if (is_dir) { | ||
1147 | if (move) { | ||
1148 | inc_nlink(old_dir); | ||
1149 | if (!unlink) | ||
1150 | drop_nlink(new_dir); | ||
1151 | } else { | ||
1152 | if (unlink) | ||
1153 | inc_nlink(old_dir); | ||
1154 | } | ||
1155 | } | ||
1156 | unlock_3_inodes(old_dir, new_dir, new_inode); | ||
1157 | ubifs_release_budget(c, &ino_req); | ||
1158 | ubifs_release_budget(c, &req); | ||
1159 | return err; | ||
1160 | } | ||
1161 | |||
1162 | int ubifs_getattr(struct vfsmount *mnt, struct dentry *dentry, | ||
1163 | struct kstat *stat) | ||
1164 | { | ||
1165 | loff_t size; | ||
1166 | struct inode *inode = dentry->d_inode; | ||
1167 | struct ubifs_inode *ui = ubifs_inode(inode); | ||
1168 | |||
1169 | mutex_lock(&ui->ui_mutex); | ||
1170 | stat->dev = inode->i_sb->s_dev; | ||
1171 | stat->ino = inode->i_ino; | ||
1172 | stat->mode = inode->i_mode; | ||
1173 | stat->nlink = inode->i_nlink; | ||
1174 | stat->uid = inode->i_uid; | ||
1175 | stat->gid = inode->i_gid; | ||
1176 | stat->rdev = inode->i_rdev; | ||
1177 | stat->atime = inode->i_atime; | ||
1178 | stat->mtime = inode->i_mtime; | ||
1179 | stat->ctime = inode->i_ctime; | ||
1180 | stat->blksize = UBIFS_BLOCK_SIZE; | ||
1181 | stat->size = ui->ui_size; | ||
1182 | |||
1183 | /* | ||
1184 | * Unfortunately, the 'stat()' system call was designed for block | ||
1185 | * device based file systems, and it is not appropriate for UBIFS, | ||
1186 | * because UBIFS does not have notion of "block". For example, it is | ||
1187 | * difficult to tell how many block a directory takes - it actually | ||
1188 | * takes less than 300 bytes, but we have to round it to block size, | ||
1189 | * which introduces large mistake. This makes utilities like 'du' to | ||
1190 | * report completely senseless numbers. This is the reason why UBIFS | ||
1191 | * goes the same way as JFFS2 - it reports zero blocks for everything | ||
1192 | * but regular files, which makes more sense than reporting completely | ||
1193 | * wrong sizes. | ||
1194 | */ | ||
1195 | if (S_ISREG(inode->i_mode)) { | ||
1196 | size = ui->xattr_size; | ||
1197 | size += stat->size; | ||
1198 | size = ALIGN(size, UBIFS_BLOCK_SIZE); | ||
1199 | /* | ||
1200 | * Note, user-space expects 512-byte blocks count irrespectively | ||
1201 | * of what was reported in @stat->size. | ||
1202 | */ | ||
1203 | stat->blocks = size >> 9; | ||
1204 | } else | ||
1205 | stat->blocks = 0; | ||
1206 | mutex_unlock(&ui->ui_mutex); | ||
1207 | return 0; | ||
1208 | } | ||
1209 | |||
1210 | struct inode_operations ubifs_dir_inode_operations = { | ||
1211 | .lookup = ubifs_lookup, | ||
1212 | .create = ubifs_create, | ||
1213 | .link = ubifs_link, | ||
1214 | .symlink = ubifs_symlink, | ||
1215 | .unlink = ubifs_unlink, | ||
1216 | .mkdir = ubifs_mkdir, | ||
1217 | .rmdir = ubifs_rmdir, | ||
1218 | .mknod = ubifs_mknod, | ||
1219 | .rename = ubifs_rename, | ||
1220 | .setattr = ubifs_setattr, | ||
1221 | .getattr = ubifs_getattr, | ||
1222 | #ifdef CONFIG_UBIFS_FS_XATTR | ||
1223 | .setxattr = ubifs_setxattr, | ||
1224 | .getxattr = ubifs_getxattr, | ||
1225 | .listxattr = ubifs_listxattr, | ||
1226 | .removexattr = ubifs_removexattr, | ||
1227 | #endif | ||
1228 | }; | ||
1229 | |||
1230 | struct file_operations ubifs_dir_operations = { | ||
1231 | .llseek = ubifs_dir_llseek, | ||
1232 | .release = ubifs_dir_release, | ||
1233 | .read = generic_read_dir, | ||
1234 | .readdir = ubifs_readdir, | ||
1235 | .fsync = ubifs_fsync, | ||
1236 | .unlocked_ioctl = ubifs_ioctl, | ||
1237 | #ifdef CONFIG_COMPAT | ||
1238 | .compat_ioctl = ubifs_compat_ioctl, | ||
1239 | #endif | ||
1240 | }; | ||