Blame view

fs/ubifs/dir.c 37.3 KB
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
  /* * This file is part of UBIFS.
   *
   * Copyright (C) 2006-2008 Nokia Corporation.
   * Copyright (C) 2006, 2007 University of Szeged, Hungary
   *
   * This program is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License version 2 as published by
   * the Free Software Foundation.
   *
   * This program is distributed in the hope that it will be useful, but WITHOUT
   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   * more details.
   *
   * You should have received a copy of the GNU General Public License along with
   * this program; if not, write to the Free Software Foundation, Inc., 51
   * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
   *
   * Authors: Artem Bityutskiy (Битюцкий Артём)
   *          Adrian Hunter
   *          Zoltan Sogor
   */
  
  /*
   * This file implements directory operations.
   *
   * All FS operations in this file allocate budget before writing anything to the
   * media. If they fail to allocate it, the error is returned. The only
   * exceptions are 'ubifs_unlink()' and 'ubifs_rmdir()' which keep working even
   * if they unable to allocate the budget, because deletion %-ENOSPC failure is
   * not what users are usually ready to get. UBIFS budgeting subsystem has some
   * space reserved for these purposes.
   *
   * All operations in this file write all inodes which they change straight
   * away, instead of marking them dirty. For example, 'ubifs_link()' changes
   * @i_size of the parent inode and writes the parent inode together with the
   * target inode. This was done to simplify file-system recovery which would
   * otherwise be very difficult to do. The only exception is rename which marks
   * the re-named inode dirty (because its @i_ctime is updated) but does not
   * write it, but just marks it as dirty.
   */
  
  #include "ubifs.h"
  
  /**
   * inherit_flags - inherit flags of the parent inode.
   * @dir: parent inode
   * @mode: new inode mode flags
   *
   * This is a helper function for 'ubifs_new_inode()' which inherits flag of the
   * parent directory inode @dir. UBIFS inodes inherit the following flags:
   * o %UBIFS_COMPR_FL, which is useful to switch compression on/of on
   *   sub-directory basis;
   * o %UBIFS_SYNC_FL - useful for the same reasons;
   * o %UBIFS_DIRSYNC_FL - similar, but relevant only to directories.
   *
   * This function returns the inherited flags.
   */
ad44be5c7   Al Viro   ubifs: propagate ...
59
  static int inherit_flags(const struct inode *dir, umode_t mode)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
  {
  	int flags;
  	const struct ubifs_inode *ui = ubifs_inode(dir);
  
  	if (!S_ISDIR(dir->i_mode))
  		/*
  		 * The parent is not a directory, which means that an extended
  		 * attribute inode is being created. No flags.
  		 */
  		return 0;
  
  	flags = ui->flags & (UBIFS_COMPR_FL | UBIFS_SYNC_FL | UBIFS_DIRSYNC_FL);
  	if (!S_ISDIR(mode))
  		/* The "DIRSYNC" flag only applies to directories */
  		flags &= ~UBIFS_DIRSYNC_FL;
  	return flags;
  }
  
  /**
   * ubifs_new_inode - allocate new UBIFS inode object.
   * @c: UBIFS file-system description object
   * @dir: parent directory inode
   * @mode: inode mode flags
   *
   * This function finds an unused inode number, allocates new inode and
   * initializes it. Returns new inode in case of success and an error code in
   * case of failure.
   */
  struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,
ad44be5c7   Al Viro   ubifs: propagate ...
89
  			      umode_t mode)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
  {
  	struct inode *inode;
  	struct ubifs_inode *ui;
  
  	inode = new_inode(c->vfs_sb);
  	ui = ubifs_inode(inode);
  	if (!inode)
  		return ERR_PTR(-ENOMEM);
  
  	/*
  	 * Set 'S_NOCMTIME' to prevent VFS form updating [mc]time of inodes and
  	 * marking them dirty in file write path (see 'file_update_time()').
  	 * UBIFS has to fully control "clean <-> dirty" transitions of inodes
  	 * to make budgeting work.
  	 */
12e776a08   Artem Bityutskiy   UBIFS: remove unn...
105
  	inode->i_flags |= S_NOCMTIME;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
106

abf5d08ac   Dmitry Monakhov   ubifs: replace in...
107
  	inode_init_owner(inode, dir, mode);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
108
109
110
  	inode->i_mtime = inode->i_atime = inode->i_ctime =
  			 ubifs_current_time(inode);
  	inode->i_mapping->nrpages = 0;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
  
  	switch (mode & S_IFMT) {
  	case S_IFREG:
  		inode->i_mapping->a_ops = &ubifs_file_address_operations;
  		inode->i_op = &ubifs_file_inode_operations;
  		inode->i_fop = &ubifs_file_operations;
  		break;
  	case S_IFDIR:
  		inode->i_op  = &ubifs_dir_inode_operations;
  		inode->i_fop = &ubifs_dir_operations;
  		inode->i_size = ui->ui_size = UBIFS_INO_NODE_SZ;
  		break;
  	case S_IFLNK:
  		inode->i_op = &ubifs_symlink_inode_operations;
  		break;
  	case S_IFSOCK:
  	case S_IFIFO:
  	case S_IFBLK:
  	case S_IFCHR:
  		inode->i_op  = &ubifs_file_inode_operations;
  		break;
  	default:
  		BUG();
  	}
  
  	ui->flags = inherit_flags(dir, mode);
  	ubifs_set_inode_flags(inode);
  	if (S_ISREG(mode))
  		ui->compr_type = c->default_compr;
  	else
  		ui->compr_type = UBIFS_COMPR_NONE;
  	ui->synced_i_size = 0;
  
  	spin_lock(&c->cnt_lock);
  	/* Inode number overflow is currently not supported */
  	if (c->highest_inum >= INUM_WARN_WATERMARK) {
  		if (c->highest_inum >= INUM_WATERMARK) {
  			spin_unlock(&c->cnt_lock);
235c362bd   Sheng Yong   UBIFS: extend deb...
149
  			ubifs_err(c, "out of inode numbers");
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
150
151
152
153
  			make_bad_inode(inode);
  			iput(inode);
  			return ERR_PTR(-EINVAL);
  		}
1a7e985dd   Sheng Yong   UBIFS: fix output...
154
  		ubifs_warn(c, "running out of inode numbers (current %lu, max %u)",
e84461ad9   Artem Bityutskiy   UBIFS: fix compil...
155
  			   (unsigned long)c->highest_inum, INUM_WATERMARK);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
156
157
158
  	}
  
  	inode->i_ino = ++c->highest_inum;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
159
160
161
162
163
164
165
166
167
168
169
  	/*
  	 * The creation sequence number remains with this inode for its
  	 * lifetime. All nodes for this inode have a greater sequence number,
  	 * and so it is possible to distinguish obsolete nodes belonging to a
  	 * previous incarnation of the same inode number - for example, for the
  	 * purpose of rebuilding the index.
  	 */
  	ui->creat_sqnum = ++c->max_sqnum;
  	spin_unlock(&c->cnt_lock);
  	return inode;
  }
bb2615d4d   Artem Bityutskiy   UBIFS: amend debu...
170
171
172
  static int dbg_check_name(const struct ubifs_info *c,
  			  const struct ubifs_dent_node *dent,
  			  const struct qstr *nm)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
173
  {
2b1844a8c   Artem Bityutskiy   UBIFS: introduce ...
174
  	if (!dbg_is_chk_gen(c))
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
175
176
177
178
179
180
181
  		return 0;
  	if (le16_to_cpu(dent->nlen) != nm->len)
  		return -EINVAL;
  	if (memcmp(dent->name, nm->name, nm->len))
  		return -EINVAL;
  	return 0;
  }
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
182
  static struct dentry *ubifs_lookup(struct inode *dir, struct dentry *dentry,
00cd8dd3b   Al Viro   stop passing name...
183
  				   unsigned int flags)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
184
185
186
187
188
189
  {
  	int err;
  	union ubifs_key key;
  	struct inode *inode = NULL;
  	struct ubifs_dent_node *dent;
  	struct ubifs_info *c = dir->i_sb->s_fs_info;
4cb2a01d8   Al Viro   ubifs: switch to %pd
190
  	dbg_gen("'%pd' in dir ino %lu", dentry, dir->i_ino);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
191
192
193
194
195
196
197
198
199
200
201
202
  
  	if (dentry->d_name.len > UBIFS_MAX_NLEN)
  		return ERR_PTR(-ENAMETOOLONG);
  
  	dent = kmalloc(UBIFS_MAX_DENT_NODE_SZ, GFP_NOFS);
  	if (!dent)
  		return ERR_PTR(-ENOMEM);
  
  	dent_key_init(c, &key, dir->i_ino, &dentry->d_name);
  
  	err = ubifs_tnc_lookup_nm(c, &key, dent, &dentry->d_name);
  	if (err) {
720b499c8   Artem Bityutskiy   UBIFS: remove unn...
203
  		if (err == -ENOENT) {
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
204
205
206
207
208
  			dbg_gen("not found");
  			goto done;
  		}
  		goto out;
  	}
bb2615d4d   Artem Bityutskiy   UBIFS: amend debu...
209
  	if (dbg_check_name(c, dent, &dentry->d_name)) {
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
210
211
212
213
214
215
216
217
218
219
220
  		err = -EINVAL;
  		goto out;
  	}
  
  	inode = ubifs_iget(dir->i_sb, le64_to_cpu(dent->inum));
  	if (IS_ERR(inode)) {
  		/*
  		 * This should not happen. Probably the file-system needs
  		 * checking.
  		 */
  		err = PTR_ERR(inode);
235c362bd   Sheng Yong   UBIFS: extend deb...
221
  		ubifs_err(c, "dead directory entry '%pd', error %d",
4cb2a01d8   Al Viro   ubifs: switch to %pd
222
  			  dentry, err);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
  		ubifs_ro_mode(c, err);
  		goto out;
  	}
  
  done:
  	kfree(dent);
  	/*
  	 * Note, d_splice_alias() would be required instead if we supported
  	 * NFS.
  	 */
  	d_add(dentry, inode);
  	return NULL;
  
  out:
  	kfree(dent);
  	return ERR_PTR(err);
  }
4acdaf27e   Al Viro   switch ->create()...
240
  static int ubifs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
ebfc3b49a   Al Viro   don't pass nameid...
241
  			bool excl)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
242
243
244
245
246
247
248
249
250
251
252
253
  {
  	struct inode *inode;
  	struct ubifs_info *c = dir->i_sb->s_fs_info;
  	int err, sz_change = CALC_DENT_SIZE(dentry->d_name.len);
  	struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1,
  					.dirtied_ino = 1 };
  	struct ubifs_inode *dir_ui = ubifs_inode(dir);
  
  	/*
  	 * Budget request settings: new inode, new direntry, changing the
  	 * parent directory inode.
  	 */
4cb2a01d8   Al Viro   ubifs: switch to %pd
254
255
  	dbg_gen("dent '%pd', mode %#hx in dir ino %lu",
  		dentry, mode, dir->i_ino);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
256
257
258
259
260
261
262
263
264
265
  
  	err = ubifs_budget_space(c, &req);
  	if (err)
  		return err;
  
  	inode = ubifs_new_inode(c, dir, mode);
  	if (IS_ERR(inode)) {
  		err = PTR_ERR(inode);
  		goto out_budg;
  	}
d7f0b70d3   Subodh Nijsure   UBIFS: Add securi...
266
267
  	err = ubifs_init_security(dir, inode, &dentry->d_name);
  	if (err)
9401a795c   Taesoo Kim   UBIFS: fix incorr...
268
  		goto out_inode;
d7f0b70d3   Subodh Nijsure   UBIFS: Add securi...
269

1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
  	mutex_lock(&dir_ui->ui_mutex);
  	dir->i_size += sz_change;
  	dir_ui->ui_size = dir->i_size;
  	dir->i_mtime = dir->i_ctime = inode->i_ctime;
  	err = ubifs_jnl_update(c, dir, &dentry->d_name, inode, 0, 0);
  	if (err)
  		goto out_cancel;
  	mutex_unlock(&dir_ui->ui_mutex);
  
  	ubifs_release_budget(c, &req);
  	insert_inode_hash(inode);
  	d_instantiate(dentry, inode);
  	return 0;
  
  out_cancel:
  	dir->i_size -= sz_change;
  	dir_ui->ui_size = dir->i_size;
  	mutex_unlock(&dir_ui->ui_mutex);
9401a795c   Taesoo Kim   UBIFS: fix incorr...
288
  out_inode:
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
289
290
291
292
  	make_bad_inode(inode);
  	iput(inode);
  out_budg:
  	ubifs_release_budget(c, &req);
235c362bd   Sheng Yong   UBIFS: extend deb...
293
  	ubifs_err(c, "cannot create regular file, error %d", err);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
294
295
  	return err;
  }
9e0a1fff8   Richard Weinberger   ubifs: Implement ...
296
297
  static int do_tmpfile(struct inode *dir, struct dentry *dentry,
  		      umode_t mode, struct inode **whiteout)
474b93704   Richard Weinberger   ubifs: Implement ...
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
  {
  	struct inode *inode;
  	struct ubifs_info *c = dir->i_sb->s_fs_info;
  	struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1};
  	struct ubifs_budget_req ino_req = { .dirtied_ino = 1 };
  	struct ubifs_inode *ui, *dir_ui = ubifs_inode(dir);
  	int err, instantiated = 0;
  
  	/*
  	 * Budget request settings: new dirty inode, new direntry,
  	 * budget for dirtied inode will be released via writeback.
  	 */
  
  	dbg_gen("dent '%pd', mode %#hx in dir ino %lu",
  		dentry, mode, dir->i_ino);
  
  	err = ubifs_budget_space(c, &req);
  	if (err)
  		return err;
  
  	err = ubifs_budget_space(c, &ino_req);
  	if (err) {
  		ubifs_release_budget(c, &req);
  		return err;
  	}
  
  	inode = ubifs_new_inode(c, dir, mode);
  	if (IS_ERR(inode)) {
  		err = PTR_ERR(inode);
  		goto out_budg;
  	}
  	ui = ubifs_inode(inode);
9e0a1fff8   Richard Weinberger   ubifs: Implement ...
330
331
332
333
  	if (whiteout) {
  		init_special_inode(inode, inode->i_mode, WHITEOUT_DEV);
  		ubifs_assert(inode->i_op == &ubifs_file_inode_operations);
  	}
474b93704   Richard Weinberger   ubifs: Implement ...
334
335
336
337
338
339
  	err = ubifs_init_security(dir, inode, &dentry->d_name);
  	if (err)
  		goto out_inode;
  
  	mutex_lock(&ui->ui_mutex);
  	insert_inode_hash(inode);
9e0a1fff8   Richard Weinberger   ubifs: Implement ...
340
341
342
343
344
345
346
347
  
  	if (whiteout) {
  		mark_inode_dirty(inode);
  		drop_nlink(inode);
  		*whiteout = inode;
  	} else {
  		d_tmpfile(dentry, inode);
  	}
474b93704   Richard Weinberger   ubifs: Implement ...
348
  	ubifs_assert(ui->dirty);
9e0a1fff8   Richard Weinberger   ubifs: Implement ...
349

474b93704   Richard Weinberger   ubifs: Implement ...
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
  	instantiated = 1;
  	mutex_unlock(&ui->ui_mutex);
  
  	mutex_lock(&dir_ui->ui_mutex);
  	err = ubifs_jnl_update(c, dir, &dentry->d_name, inode, 1, 0);
  	if (err)
  		goto out_cancel;
  	mutex_unlock(&dir_ui->ui_mutex);
  
  	ubifs_release_budget(c, &req);
  
  	return 0;
  
  out_cancel:
  	mutex_unlock(&dir_ui->ui_mutex);
  out_inode:
  	make_bad_inode(inode);
  	if (!instantiated)
  		iput(inode);
  out_budg:
  	ubifs_release_budget(c, &req);
  	if (!instantiated)
  		ubifs_release_budget(c, &ino_req);
  	ubifs_err(c, "cannot create temporary file, error %d", err);
  	return err;
  }
9e0a1fff8   Richard Weinberger   ubifs: Implement ...
376
377
378
379
380
  static int ubifs_tmpfile(struct inode *dir, struct dentry *dentry,
  			 umode_t mode)
  {
  	return do_tmpfile(dir, dentry, mode, NULL);
  }
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
  /**
   * vfs_dent_type - get VFS directory entry type.
   * @type: UBIFS directory entry type
   *
   * This function converts UBIFS directory entry type into VFS directory entry
   * type.
   */
  static unsigned int vfs_dent_type(uint8_t type)
  {
  	switch (type) {
  	case UBIFS_ITYPE_REG:
  		return DT_REG;
  	case UBIFS_ITYPE_DIR:
  		return DT_DIR;
  	case UBIFS_ITYPE_LNK:
  		return DT_LNK;
  	case UBIFS_ITYPE_BLK:
  		return DT_BLK;
  	case UBIFS_ITYPE_CHR:
  		return DT_CHR;
  	case UBIFS_ITYPE_FIFO:
  		return DT_FIFO;
  	case UBIFS_ITYPE_SOCK:
  		return DT_SOCK;
  	default:
  		BUG();
  	}
  	return 0;
  }
  
  /*
   * The classical Unix view for directory is that it is a linear array of
   * (name, inode number) entries. Linux/VFS assumes this model as well.
   * Particularly, 'readdir()' call wants us to return a directory entry offset
   * which later may be used to continue 'readdir()'ing the directory or to
   * 'seek()' to that specific direntry. Obviously UBIFS does not really fit this
   * model because directory entries are identified by keys, which may collide.
   *
   * UBIFS uses directory entry hash value for directory offsets, so
   * 'seekdir()'/'telldir()' may not always work because of possible key
   * collisions. But UBIFS guarantees that consecutive 'readdir()' calls work
   * properly by means of saving full directory entry name in the private field
   * of the file description object.
   *
   * This means that UBIFS cannot support NFS which requires full
   * 'seekdir()'/'telldir()' support.
   */
01122e068   Al Viro   [readdir] convert...
428
  static int ubifs_readdir(struct file *file, struct dir_context *ctx)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
429
  {
c83ed4c9d   Richard Weinberger   ubifs: Abort read...
430
  	int err = 0;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
431
432
433
  	struct qstr nm;
  	union ubifs_key key;
  	struct ubifs_dent_node *dent;
496ad9aa8   Al Viro   new helper: file_...
434
  	struct inode *dir = file_inode(file);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
435
  	struct ubifs_info *c = dir->i_sb->s_fs_info;
01122e068   Al Viro   [readdir] convert...
436
  	dbg_gen("dir ino %lu, f_pos %#llx", dir->i_ino, ctx->pos);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
437

01122e068   Al Viro   [readdir] convert...
438
  	if (ctx->pos > UBIFS_S_KEY_HASH_MASK || ctx->pos == 2)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
439
440
441
442
443
  		/*
  		 * The directory was seek'ed to a senseless position or there
  		 * are no more entries.
  		 */
  		return 0;
605c912bb   Artem Bityutskiy   UBIFS: fix a horr...
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
  	if (file->f_version == 0) {
  		/*
  		 * The file was seek'ed, which means that @file->private_data
  		 * is now invalid. This may also be just the first
  		 * 'ubifs_readdir()' invocation, in which case
  		 * @file->private_data is NULL, and the below code is
  		 * basically a no-op.
  		 */
  		kfree(file->private_data);
  		file->private_data = NULL;
  	}
  
  	/*
  	 * 'generic_file_llseek()' unconditionally sets @file->f_version to
  	 * zero, and we use this for detecting whether the file was seek'ed.
  	 */
  	file->f_version = 1;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
461
  	/* File positions 0 and 1 correspond to "." and ".." */
01122e068   Al Viro   [readdir] convert...
462
  	if (ctx->pos < 2) {
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
463
  		ubifs_assert(!file->private_data);
01122e068   Al Viro   [readdir] convert...
464
  		if (!dir_emit_dots(file, ctx))
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
465
466
467
468
469
470
471
472
473
474
  			return 0;
  
  		/* Find the first entry in TNC and save it */
  		lowest_dent_key(c, &key, dir->i_ino);
  		nm.name = NULL;
  		dent = ubifs_tnc_next_ent(c, &key, &nm);
  		if (IS_ERR(dent)) {
  			err = PTR_ERR(dent);
  			goto out;
  		}
01122e068   Al Viro   [readdir] convert...
475
  		ctx->pos = key_hash_flash(c, &dent->key);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
476
477
478
479
480
481
482
  		file->private_data = dent;
  	}
  
  	dent = file->private_data;
  	if (!dent) {
  		/*
  		 * The directory was seek'ed to and is now readdir'ed.
01122e068   Al Viro   [readdir] convert...
483
  		 * Find the entry corresponding to @ctx->pos or the closest one.
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
484
  		 */
01122e068   Al Viro   [readdir] convert...
485
  		dent_key_init_hash(c, &key, dir->i_ino, ctx->pos);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
486
487
488
489
490
491
  		nm.name = NULL;
  		dent = ubifs_tnc_next_ent(c, &key, &nm);
  		if (IS_ERR(dent)) {
  			err = PTR_ERR(dent);
  			goto out;
  		}
01122e068   Al Viro   [readdir] convert...
492
  		ctx->pos = key_hash_flash(c, &dent->key);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
493
494
495
496
497
  		file->private_data = dent;
  	}
  
  	while (1) {
  		dbg_gen("feed '%s', ino %llu, new f_pos %#x",
7424bac82   Alexander Beregalov   UBIFS: fix printk...
498
  			dent->name, (unsigned long long)le64_to_cpu(dent->inum),
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
499
  			key_hash_flash(c, &dent->key));
0ecb9529a   Harvey Harrison   UBIFS: endian han...
500
501
  		ubifs_assert(le64_to_cpu(dent->ch.sqnum) >
  			     ubifs_inode(dir)->creat_sqnum);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
502
503
  
  		nm.len = le16_to_cpu(dent->nlen);
01122e068   Al Viro   [readdir] convert...
504
  		if (!dir_emit(ctx, dent->name, nm.len,
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
505
  			       le64_to_cpu(dent->inum),
01122e068   Al Viro   [readdir] convert...
506
  			       vfs_dent_type(dent->type)))
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
507
508
509
510
511
512
513
514
515
516
517
518
  			return 0;
  
  		/* Switch to the next entry */
  		key_read(c, &dent->key, &key);
  		nm.name = dent->name;
  		dent = ubifs_tnc_next_ent(c, &key, &nm);
  		if (IS_ERR(dent)) {
  			err = PTR_ERR(dent);
  			goto out;
  		}
  
  		kfree(file->private_data);
01122e068   Al Viro   [readdir] convert...
519
  		ctx->pos = key_hash_flash(c, &dent->key);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
520
521
522
523
524
  		file->private_data = dent;
  		cond_resched();
  	}
  
  out:
aeeb14f76   Richard Weinberger   UBIFS: Fix possib...
525
526
  	kfree(file->private_data);
  	file->private_data = NULL;
c83ed4c9d   Richard Weinberger   ubifs: Abort read...
527
  	if (err != -ENOENT)
235c362bd   Sheng Yong   UBIFS: extend deb...
528
  		ubifs_err(c, "cannot find next direntry, error %d", err);
a00052a29   Richard Weinberger   ubifs: Fix regres...
529
530
531
532
533
534
535
  	else
  		/*
  		 * -ENOENT is a non-fatal error in this context, the TNC uses
  		 * it to indicate that the cursor moved past the current directory
  		 * and readdir() has to stop.
  		 */
  		err = 0;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
536

605c912bb   Artem Bityutskiy   UBIFS: fix a horr...
537
  	/* 2 is a special value indicating that there are no more direntries */
01122e068   Al Viro   [readdir] convert...
538
  	ctx->pos = 2;
c83ed4c9d   Richard Weinberger   ubifs: Abort read...
539
  	return err;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
540
  }
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
541
542
543
544
545
546
547
548
549
  /* Free saved readdir() state when the directory is closed */
  static int ubifs_dir_release(struct inode *dir, struct file *file)
  {
  	kfree(file->private_data);
  	file->private_data = NULL;
  	return 0;
  }
  
  /**
82c1593ca   Artem Bityutskiy   UBIFS: simplify l...
550
   * lock_2_inodes - a wrapper for locking two UBIFS inodes.
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
551
552
   * @inode1: first inode
   * @inode2: second inode
82c1593ca   Artem Bityutskiy   UBIFS: simplify l...
553
554
555
556
   *
   * We do not implement any tricks to guarantee strict lock ordering, because
   * VFS has already done it for us on the @i_mutex. So this is just a simple
   * wrapper function.
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
557
558
559
   */
  static void lock_2_inodes(struct inode *inode1, struct inode *inode2)
  {
82c1593ca   Artem Bityutskiy   UBIFS: simplify l...
560
561
  	mutex_lock_nested(&ubifs_inode(inode1)->ui_mutex, WB_MUTEX_1);
  	mutex_lock_nested(&ubifs_inode(inode2)->ui_mutex, WB_MUTEX_2);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
562
563
564
  }
  
  /**
82c1593ca   Artem Bityutskiy   UBIFS: simplify l...
565
   * unlock_2_inodes - a wrapper for unlocking two UBIFS inodes.
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
566
567
568
569
570
   * @inode1: first inode
   * @inode2: second inode
   */
  static void unlock_2_inodes(struct inode *inode1, struct inode *inode2)
  {
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
571
  	mutex_unlock(&ubifs_inode(inode2)->ui_mutex);
82c1593ca   Artem Bityutskiy   UBIFS: simplify l...
572
  	mutex_unlock(&ubifs_inode(inode1)->ui_mutex);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
573
574
575
576
577
578
  }
  
  static int ubifs_link(struct dentry *old_dentry, struct inode *dir,
  		      struct dentry *dentry)
  {
  	struct ubifs_info *c = dir->i_sb->s_fs_info;
2b0143b5c   David Howells   VFS: normal files...
579
  	struct inode *inode = d_inode(old_dentry);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
580
581
582
583
  	struct ubifs_inode *ui = ubifs_inode(inode);
  	struct ubifs_inode *dir_ui = ubifs_inode(dir);
  	int err, sz_change = CALC_DENT_SIZE(dentry->d_name.len);
  	struct ubifs_budget_req req = { .new_dent = 1, .dirtied_ino = 2,
dab4b4d2f   Artem Bityutskiy   UBIFS: align inod...
584
  				.dirtied_ino_d = ALIGN(ui->data_len, 8) };
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
585
586
587
588
589
  
  	/*
  	 * Budget request settings: new direntry, changing the target inode,
  	 * changing the parent inode.
  	 */
4cb2a01d8   Al Viro   ubifs: switch to %pd
590
591
  	dbg_gen("dent '%pd' to ino %lu (nlink %d) in dir ino %lu",
  		dentry, inode->i_ino,
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
592
  		inode->i_nlink, dir->i_ino);
5955102c9   Al Viro   wrappers for ->i_...
593
594
  	ubifs_assert(inode_is_locked(dir));
  	ubifs_assert(inode_is_locked(inode));
8b3884a84   Hunter Adrian   UBIFS: return err...
595

d808efb40   Artem Bityutskiy   UBIFS: amend debu...
596
  	err = dbg_check_synced_i_size(c, inode);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
597
598
599
600
601
602
603
604
  	if (err)
  		return err;
  
  	err = ubifs_budget_space(c, &req);
  	if (err)
  		return err;
  
  	lock_2_inodes(dir, inode);
b93858556   Richard Weinberger   ubifs: Fix O_TMPF...
605
606
607
608
  
  	/* Handle O_TMPFILE corner case, it is allowed to link a O_TMPFILE. */
  	if (inode->i_nlink == 0)
  		ubifs_delete_orphan(c, inode->i_ino);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
609
  	inc_nlink(inode);
7de9c6ee3   Al Viro   new helper: ihold()
610
  	ihold(inode);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
  	inode->i_ctime = ubifs_current_time(inode);
  	dir->i_size += sz_change;
  	dir_ui->ui_size = dir->i_size;
  	dir->i_mtime = dir->i_ctime = inode->i_ctime;
  	err = ubifs_jnl_update(c, dir, &dentry->d_name, inode, 0, 0);
  	if (err)
  		goto out_cancel;
  	unlock_2_inodes(dir, inode);
  
  	ubifs_release_budget(c, &req);
  	d_instantiate(dentry, inode);
  	return 0;
  
  out_cancel:
  	dir->i_size -= sz_change;
  	dir_ui->ui_size = dir->i_size;
  	drop_nlink(inode);
b93858556   Richard Weinberger   ubifs: Fix O_TMPF...
628
629
  	if (inode->i_nlink == 0)
  		ubifs_add_orphan(c, inode->i_ino);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
630
631
632
633
634
635
636
637
638
  	unlock_2_inodes(dir, inode);
  	ubifs_release_budget(c, &req);
  	iput(inode);
  	return err;
  }
  
  static int ubifs_unlink(struct inode *dir, struct dentry *dentry)
  {
  	struct ubifs_info *c = dir->i_sb->s_fs_info;
2b0143b5c   David Howells   VFS: normal files...
639
  	struct inode *inode = d_inode(dentry);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
640
641
642
643
  	struct ubifs_inode *dir_ui = ubifs_inode(dir);
  	int sz_change = CALC_DENT_SIZE(dentry->d_name.len);
  	int err, budgeted = 1;
  	struct ubifs_budget_req req = { .mod_dent = 1, .dirtied_ino = 2 };
c43be1085   Artem Bityutskiy   UBIFS: do not use...
644
  	unsigned int saved_nlink = inode->i_nlink;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
645
646
647
648
649
650
651
  
  	/*
  	 * Budget request settings: deletion direntry, deletion inode (+1 for
  	 * @dirtied_ino), changing the parent directory inode. If budgeting
  	 * fails, go ahead anyway because we have extra space reserved for
  	 * deletions.
  	 */
4cb2a01d8   Al Viro   ubifs: switch to %pd
652
653
  	dbg_gen("dent '%pd' from ino %lu (nlink %d) in dir ino %lu",
  		dentry, inode->i_ino,
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
654
  		inode->i_nlink, dir->i_ino);
5955102c9   Al Viro   wrappers for ->i_...
655
656
  	ubifs_assert(inode_is_locked(dir));
  	ubifs_assert(inode_is_locked(inode));
d808efb40   Artem Bityutskiy   UBIFS: amend debu...
657
  	err = dbg_check_synced_i_size(c, inode);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
658
659
660
661
662
663
664
  	if (err)
  		return err;
  
  	err = ubifs_budget_space(c, &req);
  	if (err) {
  		if (err != -ENOSPC)
  			return err;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
  		budgeted = 0;
  	}
  
  	lock_2_inodes(dir, inode);
  	inode->i_ctime = ubifs_current_time(dir);
  	drop_nlink(inode);
  	dir->i_size -= sz_change;
  	dir_ui->ui_size = dir->i_size;
  	dir->i_mtime = dir->i_ctime = inode->i_ctime;
  	err = ubifs_jnl_update(c, dir, &dentry->d_name, inode, 1, 0);
  	if (err)
  		goto out_cancel;
  	unlock_2_inodes(dir, inode);
  
  	if (budgeted)
  		ubifs_release_budget(c, &req);
  	else {
  		/* We've deleted something - clean the "no space" flags */
b137545c4   Artem Bityutskiy   UBIFS: introduce ...
683
  		c->bi.nospace = c->bi.nospace_rp = 0;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
684
685
686
687
688
689
690
  		smp_wmb();
  	}
  	return 0;
  
  out_cancel:
  	dir->i_size += sz_change;
  	dir_ui->ui_size = dir->i_size;
c43be1085   Artem Bityutskiy   UBIFS: do not use...
691
  	set_nlink(inode, saved_nlink);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
  	unlock_2_inodes(dir, inode);
  	if (budgeted)
  		ubifs_release_budget(c, &req);
  	return err;
  }
  
  /**
   * check_dir_empty - check if a directory is empty or not.
   * @c: UBIFS file-system description object
   * @dir: VFS inode object of the directory to check
   *
   * This function checks if directory @dir is empty. Returns zero if the
   * directory is empty, %-ENOTEMPTY if it is not, and other negative error codes
   * in case of of errors.
   */
  static int check_dir_empty(struct ubifs_info *c, struct inode *dir)
  {
  	struct qstr nm = { .name = NULL };
  	struct ubifs_dent_node *dent;
  	union ubifs_key key;
  	int err;
  
  	lowest_dent_key(c, &key, dir->i_ino);
  	dent = ubifs_tnc_next_ent(c, &key, &nm);
  	if (IS_ERR(dent)) {
  		err = PTR_ERR(dent);
  		if (err == -ENOENT)
  			err = 0;
  	} else {
  		kfree(dent);
  		err = -ENOTEMPTY;
  	}
  	return err;
  }
  
  static int ubifs_rmdir(struct inode *dir, struct dentry *dentry)
  {
  	struct ubifs_info *c = dir->i_sb->s_fs_info;
2b0143b5c   David Howells   VFS: normal files...
730
  	struct inode *inode = d_inode(dentry);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
731
732
733
734
735
736
737
738
739
740
  	int sz_change = CALC_DENT_SIZE(dentry->d_name.len);
  	int err, budgeted = 1;
  	struct ubifs_inode *dir_ui = ubifs_inode(dir);
  	struct ubifs_budget_req req = { .mod_dent = 1, .dirtied_ino = 2 };
  
  	/*
  	 * Budget request settings: deletion direntry, deletion inode and
  	 * changing the parent inode. If budgeting fails, go ahead anyway
  	 * because we have extra space reserved for deletions.
  	 */
4cb2a01d8   Al Viro   ubifs: switch to %pd
741
742
  	dbg_gen("directory '%pd', ino %lu in dir ino %lu", dentry,
  		inode->i_ino, dir->i_ino);
5955102c9   Al Viro   wrappers for ->i_...
743
744
  	ubifs_assert(inode_is_locked(dir));
  	ubifs_assert(inode_is_locked(inode));
2b0143b5c   David Howells   VFS: normal files...
745
  	err = check_dir_empty(c, d_inode(dentry));
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
  	if (err)
  		return err;
  
  	err = ubifs_budget_space(c, &req);
  	if (err) {
  		if (err != -ENOSPC)
  			return err;
  		budgeted = 0;
  	}
  
  	lock_2_inodes(dir, inode);
  	inode->i_ctime = ubifs_current_time(dir);
  	clear_nlink(inode);
  	drop_nlink(dir);
  	dir->i_size -= sz_change;
  	dir_ui->ui_size = dir->i_size;
  	dir->i_mtime = dir->i_ctime = inode->i_ctime;
  	err = ubifs_jnl_update(c, dir, &dentry->d_name, inode, 1, 0);
  	if (err)
  		goto out_cancel;
  	unlock_2_inodes(dir, inode);
  
  	if (budgeted)
  		ubifs_release_budget(c, &req);
  	else {
  		/* We've deleted something - clean the "no space" flags */
b137545c4   Artem Bityutskiy   UBIFS: introduce ...
772
  		c->bi.nospace = c->bi.nospace_rp = 0;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
773
774
775
776
777
778
779
780
  		smp_wmb();
  	}
  	return 0;
  
  out_cancel:
  	dir->i_size += sz_change;
  	dir_ui->ui_size = dir->i_size;
  	inc_nlink(dir);
c43be1085   Artem Bityutskiy   UBIFS: do not use...
781
  	set_nlink(inode, 2);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
782
783
784
785
786
  	unlock_2_inodes(dir, inode);
  	if (budgeted)
  		ubifs_release_budget(c, &req);
  	return err;
  }
18bb1db3e   Al Viro   switch vfs_mkdir(...
787
  static int ubifs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
788
789
790
791
792
  {
  	struct inode *inode;
  	struct ubifs_inode *dir_ui = ubifs_inode(dir);
  	struct ubifs_info *c = dir->i_sb->s_fs_info;
  	int err, sz_change = CALC_DENT_SIZE(dentry->d_name.len);
182854b46   Artem Bityutskiy   UBIFS: fix budget...
793
  	struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1 };
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
794
795
796
797
798
  
  	/*
  	 * Budget request settings: new inode, new direntry and changing parent
  	 * directory inode.
  	 */
4cb2a01d8   Al Viro   ubifs: switch to %pd
799
800
  	dbg_gen("dent '%pd', mode %#hx in dir ino %lu",
  		dentry, mode, dir->i_ino);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
801
802
803
804
805
806
807
808
809
810
  
  	err = ubifs_budget_space(c, &req);
  	if (err)
  		return err;
  
  	inode = ubifs_new_inode(c, dir, S_IFDIR | mode);
  	if (IS_ERR(inode)) {
  		err = PTR_ERR(inode);
  		goto out_budg;
  	}
d7f0b70d3   Subodh Nijsure   UBIFS: Add securi...
811
812
  	err = ubifs_init_security(dir, inode, &dentry->d_name);
  	if (err)
9401a795c   Taesoo Kim   UBIFS: fix incorr...
813
  		goto out_inode;
d7f0b70d3   Subodh Nijsure   UBIFS: Add securi...
814

1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
815
816
817
818
819
820
821
822
823
  	mutex_lock(&dir_ui->ui_mutex);
  	insert_inode_hash(inode);
  	inc_nlink(inode);
  	inc_nlink(dir);
  	dir->i_size += sz_change;
  	dir_ui->ui_size = dir->i_size;
  	dir->i_mtime = dir->i_ctime = inode->i_ctime;
  	err = ubifs_jnl_update(c, dir, &dentry->d_name, inode, 0, 0);
  	if (err) {
235c362bd   Sheng Yong   UBIFS: extend deb...
824
  		ubifs_err(c, "cannot create directory, error %d", err);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
825
826
827
828
829
830
831
832
833
834
835
836
837
  		goto out_cancel;
  	}
  	mutex_unlock(&dir_ui->ui_mutex);
  
  	ubifs_release_budget(c, &req);
  	d_instantiate(dentry, inode);
  	return 0;
  
  out_cancel:
  	dir->i_size -= sz_change;
  	dir_ui->ui_size = dir->i_size;
  	drop_nlink(dir);
  	mutex_unlock(&dir_ui->ui_mutex);
9401a795c   Taesoo Kim   UBIFS: fix incorr...
838
  out_inode:
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
839
840
841
842
843
844
845
846
  	make_bad_inode(inode);
  	iput(inode);
  out_budg:
  	ubifs_release_budget(c, &req);
  	return err;
  }
  
  static int ubifs_mknod(struct inode *dir, struct dentry *dentry,
1a67aafb5   Al Viro   switch ->mknod() ...
847
  		       umode_t mode, dev_t rdev)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
848
849
850
851
852
853
854
855
856
  {
  	struct inode *inode;
  	struct ubifs_inode *ui;
  	struct ubifs_inode *dir_ui = ubifs_inode(dir);
  	struct ubifs_info *c = dir->i_sb->s_fs_info;
  	union ubifs_dev_desc *dev = NULL;
  	int sz_change = CALC_DENT_SIZE(dentry->d_name.len);
  	int err, devlen = 0;
  	struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1,
dab4b4d2f   Artem Bityutskiy   UBIFS: align inod...
857
858
  					.new_ino_d = ALIGN(devlen, 8),
  					.dirtied_ino = 1 };
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
859
860
861
862
863
  
  	/*
  	 * Budget request settings: new inode, new direntry and changing parent
  	 * directory inode.
  	 */
4cb2a01d8   Al Viro   ubifs: switch to %pd
864
  	dbg_gen("dent '%pd' in dir ino %lu", dentry, dir->i_ino);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
865

1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
  	if (S_ISBLK(mode) || S_ISCHR(mode)) {
  		dev = kmalloc(sizeof(union ubifs_dev_desc), GFP_NOFS);
  		if (!dev)
  			return -ENOMEM;
  		devlen = ubifs_encode_dev(dev, rdev);
  	}
  
  	err = ubifs_budget_space(c, &req);
  	if (err) {
  		kfree(dev);
  		return err;
  	}
  
  	inode = ubifs_new_inode(c, dir, mode);
  	if (IS_ERR(inode)) {
  		kfree(dev);
  		err = PTR_ERR(inode);
  		goto out_budg;
  	}
  
  	init_special_inode(inode, inode->i_mode, rdev);
  	inode->i_size = ubifs_inode(inode)->ui_size = devlen;
  	ui = ubifs_inode(inode);
  	ui->data = dev;
  	ui->data_len = devlen;
d7f0b70d3   Subodh Nijsure   UBIFS: Add securi...
891
892
  	err = ubifs_init_security(dir, inode, &dentry->d_name);
  	if (err)
9401a795c   Taesoo Kim   UBIFS: fix incorr...
893
  		goto out_inode;
d7f0b70d3   Subodh Nijsure   UBIFS: Add securi...
894

1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
  	mutex_lock(&dir_ui->ui_mutex);
  	dir->i_size += sz_change;
  	dir_ui->ui_size = dir->i_size;
  	dir->i_mtime = dir->i_ctime = inode->i_ctime;
  	err = ubifs_jnl_update(c, dir, &dentry->d_name, inode, 0, 0);
  	if (err)
  		goto out_cancel;
  	mutex_unlock(&dir_ui->ui_mutex);
  
  	ubifs_release_budget(c, &req);
  	insert_inode_hash(inode);
  	d_instantiate(dentry, inode);
  	return 0;
  
  out_cancel:
  	dir->i_size -= sz_change;
  	dir_ui->ui_size = dir->i_size;
  	mutex_unlock(&dir_ui->ui_mutex);
9401a795c   Taesoo Kim   UBIFS: fix incorr...
913
  out_inode:
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
  	make_bad_inode(inode);
  	iput(inode);
  out_budg:
  	ubifs_release_budget(c, &req);
  	return err;
  }
  
  static int ubifs_symlink(struct inode *dir, struct dentry *dentry,
  			 const char *symname)
  {
  	struct inode *inode;
  	struct ubifs_inode *ui;
  	struct ubifs_inode *dir_ui = ubifs_inode(dir);
  	struct ubifs_info *c = dir->i_sb->s_fs_info;
  	int err, len = strlen(symname);
  	int sz_change = CALC_DENT_SIZE(dentry->d_name.len);
  	struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1,
dab4b4d2f   Artem Bityutskiy   UBIFS: align inod...
931
932
  					.new_ino_d = ALIGN(len, 8),
  					.dirtied_ino = 1 };
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
933
934
935
936
937
  
  	/*
  	 * Budget request settings: new inode, new direntry and changing parent
  	 * directory inode.
  	 */
4cb2a01d8   Al Viro   ubifs: switch to %pd
938
939
  	dbg_gen("dent '%pd', target '%s' in dir ino %lu", dentry,
  		symname, dir->i_ino);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
  
  	if (len > UBIFS_MAX_INO_DATA)
  		return -ENAMETOOLONG;
  
  	err = ubifs_budget_space(c, &req);
  	if (err)
  		return err;
  
  	inode = ubifs_new_inode(c, dir, S_IFLNK | S_IRWXUGO);
  	if (IS_ERR(inode)) {
  		err = PTR_ERR(inode);
  		goto out_budg;
  	}
  
  	ui = ubifs_inode(inode);
  	ui->data = kmalloc(len + 1, GFP_NOFS);
  	if (!ui->data) {
  		err = -ENOMEM;
  		goto out_inode;
  	}
  
  	memcpy(ui->data, symname, len);
  	((char *)ui->data)[len] = '\0';
0f301bd30   Al Viro   ubifs: switch to ...
963
  	inode->i_link = ui->data;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
964
965
966
967
968
969
970
  	/*
  	 * The terminating zero byte is not written to the flash media and it
  	 * is put just to make later in-memory string processing simpler. Thus,
  	 * data length is @len, not @len + %1.
  	 */
  	ui->data_len = len;
  	inode->i_size = ubifs_inode(inode)->ui_size = len;
d7f0b70d3   Subodh Nijsure   UBIFS: Add securi...
971
972
  	err = ubifs_init_security(dir, inode, &dentry->d_name);
  	if (err)
9401a795c   Taesoo Kim   UBIFS: fix incorr...
973
  		goto out_inode;
d7f0b70d3   Subodh Nijsure   UBIFS: Add securi...
974

1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
  	mutex_lock(&dir_ui->ui_mutex);
  	dir->i_size += sz_change;
  	dir_ui->ui_size = dir->i_size;
  	dir->i_mtime = dir->i_ctime = inode->i_ctime;
  	err = ubifs_jnl_update(c, dir, &dentry->d_name, inode, 0, 0);
  	if (err)
  		goto out_cancel;
  	mutex_unlock(&dir_ui->ui_mutex);
  
  	ubifs_release_budget(c, &req);
  	insert_inode_hash(inode);
  	d_instantiate(dentry, inode);
  	return 0;
  
  out_cancel:
  	dir->i_size -= sz_change;
  	dir_ui->ui_size = dir->i_size;
  	mutex_unlock(&dir_ui->ui_mutex);
  out_inode:
  	make_bad_inode(inode);
  	iput(inode);
  out_budg:
  	ubifs_release_budget(c, &req);
  	return err;
  }
  
  /**
9e0a1fff8   Richard Weinberger   ubifs: Implement ...
1002
   * lock_4_inodes - a wrapper for locking three UBIFS inodes.
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1003
1004
1005
   * @inode1: first inode
   * @inode2: second inode
   * @inode3: third inode
9e0a1fff8   Richard Weinberger   ubifs: Implement ...
1006
   * @inode4: fouth inode
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1007
   *
82c1593ca   Artem Bityutskiy   UBIFS: simplify l...
1008
   * This function is used for 'ubifs_rename()' and @inode1 may be the same as
9e0a1fff8   Richard Weinberger   ubifs: Implement ...
1009
   * @inode2 whereas @inode3 and @inode4 may be %NULL.
82c1593ca   Artem Bityutskiy   UBIFS: simplify l...
1010
1011
1012
1013
   *
   * We do not implement any tricks to guarantee strict lock ordering, because
   * VFS has already done it for us on the @i_mutex. So this is just a simple
   * wrapper function.
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1014
   */
9e0a1fff8   Richard Weinberger   ubifs: Implement ...
1015
1016
  static void lock_4_inodes(struct inode *inode1, struct inode *inode2,
  			  struct inode *inode3, struct inode *inode4)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1017
  {
82c1593ca   Artem Bityutskiy   UBIFS: simplify l...
1018
1019
1020
1021
1022
  	mutex_lock_nested(&ubifs_inode(inode1)->ui_mutex, WB_MUTEX_1);
  	if (inode2 != inode1)
  		mutex_lock_nested(&ubifs_inode(inode2)->ui_mutex, WB_MUTEX_2);
  	if (inode3)
  		mutex_lock_nested(&ubifs_inode(inode3)->ui_mutex, WB_MUTEX_3);
9e0a1fff8   Richard Weinberger   ubifs: Implement ...
1023
1024
  	if (inode4)
  		mutex_lock_nested(&ubifs_inode(inode4)->ui_mutex, WB_MUTEX_4);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1025
1026
1027
  }
  
  /**
9e0a1fff8   Richard Weinberger   ubifs: Implement ...
1028
   * unlock_4_inodes - a wrapper for unlocking three UBIFS inodes for rename.
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1029
1030
1031
   * @inode1: first inode
   * @inode2: second inode
   * @inode3: third inode
9e0a1fff8   Richard Weinberger   ubifs: Implement ...
1032
   * @inode4: fouth inode
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1033
   */
9e0a1fff8   Richard Weinberger   ubifs: Implement ...
1034
1035
  static void unlock_4_inodes(struct inode *inode1, struct inode *inode2,
  			    struct inode *inode3, struct inode *inode4)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1036
  {
9e0a1fff8   Richard Weinberger   ubifs: Implement ...
1037
1038
  	if (inode4)
  		mutex_unlock(&ubifs_inode(inode4)->ui_mutex);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1039
1040
  	if (inode3)
  		mutex_unlock(&ubifs_inode(inode3)->ui_mutex);
82c1593ca   Artem Bityutskiy   UBIFS: simplify l...
1041
1042
1043
  	if (inode1 != inode2)
  		mutex_unlock(&ubifs_inode(inode2)->ui_mutex);
  	mutex_unlock(&ubifs_inode(inode1)->ui_mutex);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1044
  }
390975ac3   Richard Weinberger   ubifs: Rename ubi...
1045
1046
1047
  static int do_rename(struct inode *old_dir, struct dentry *old_dentry,
  		     struct inode *new_dir, struct dentry *new_dentry,
  		     unsigned int flags)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1048
1049
  {
  	struct ubifs_info *c = old_dir->i_sb->s_fs_info;
2b0143b5c   David Howells   VFS: normal files...
1050
1051
  	struct inode *old_inode = d_inode(old_dentry);
  	struct inode *new_inode = d_inode(new_dentry);
9e0a1fff8   Richard Weinberger   ubifs: Implement ...
1052
  	struct inode *whiteout = NULL;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1053
  	struct ubifs_inode *old_inode_ui = ubifs_inode(old_inode);
9e0a1fff8   Richard Weinberger   ubifs: Implement ...
1054
  	struct ubifs_inode *whiteout_ui = NULL;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1055
1056
1057
1058
1059
1060
1061
1062
  	int err, release, sync = 0, move = (new_dir != old_dir);
  	int is_dir = S_ISDIR(old_inode->i_mode);
  	int unlink = !!new_inode;
  	int new_sz = CALC_DENT_SIZE(new_dentry->d_name.len);
  	int old_sz = CALC_DENT_SIZE(old_dentry->d_name.len);
  	struct ubifs_budget_req req = { .new_dent = 1, .mod_dent = 1,
  					.dirtied_ino = 3 };
  	struct ubifs_budget_req ino_req = { .dirtied_ino = 1,
dab4b4d2f   Artem Bityutskiy   UBIFS: align inod...
1063
  			.dirtied_ino_d = ALIGN(old_inode_ui->data_len, 8) };
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1064
  	struct timespec time;
782759b9f   Alexandre Pereira da Silva   UBIFS: fix compil...
1065
  	unsigned int uninitialized_var(saved_nlink);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1066
1067
1068
1069
1070
1071
1072
1073
1074
  
  	/*
  	 * Budget request settings: deletion direntry, new direntry, removing
  	 * the old inode, and changing old and new parent directory inodes.
  	 *
  	 * However, this operation also marks the target inode as dirty and
  	 * does not write it, so we allocate budget for the target inode
  	 * separately.
  	 */
9e0a1fff8   Richard Weinberger   ubifs: Implement ...
1075
  	dbg_gen("dent '%pd' ino %lu in dir ino %lu to dent '%pd' in dir ino %lu flags 0x%x",
4cb2a01d8   Al Viro   ubifs: switch to %pd
1076
  		old_dentry, old_inode->i_ino, old_dir->i_ino,
9e0a1fff8   Richard Weinberger   ubifs: Implement ...
1077
  		new_dentry, new_dir->i_ino, flags);
82c1593ca   Artem Bityutskiy   UBIFS: simplify l...
1078
  	if (unlink)
5955102c9   Al Viro   wrappers for ->i_...
1079
  		ubifs_assert(inode_is_locked(new_inode));
82c1593ca   Artem Bityutskiy   UBIFS: simplify l...
1080

1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
  	if (unlink && is_dir) {
  		err = check_dir_empty(c, new_inode);
  		if (err)
  			return err;
  	}
  
  	err = ubifs_budget_space(c, &req);
  	if (err)
  		return err;
  	err = ubifs_budget_space(c, &ino_req);
  	if (err) {
  		ubifs_release_budget(c, &req);
  		return err;
  	}
9e0a1fff8   Richard Weinberger   ubifs: Implement ...
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
  	if (flags & RENAME_WHITEOUT) {
  		union ubifs_dev_desc *dev = NULL;
  
  		dev = kmalloc(sizeof(union ubifs_dev_desc), GFP_NOFS);
  		if (!dev) {
  			ubifs_release_budget(c, &req);
  			ubifs_release_budget(c, &ino_req);
  			return -ENOMEM;
  		}
  
  		err = do_tmpfile(old_dir, old_dentry, S_IFCHR | WHITEOUT_MODE, &whiteout);
  		if (err) {
  			ubifs_release_budget(c, &req);
  			ubifs_release_budget(c, &ino_req);
  			kfree(dev);
  			return err;
  		}
  
  		whiteout->i_state |= I_LINKABLE;
  		whiteout_ui = ubifs_inode(whiteout);
  		whiteout_ui->data = dev;
  		whiteout_ui->data_len = ubifs_encode_dev(dev, MKDEV(0, 0));
  		ubifs_assert(!whiteout_ui->dirty);
  	}
  
  	lock_4_inodes(old_dir, new_dir, new_inode, whiteout);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
  
  	/*
  	 * Like most other Unix systems, set the @i_ctime for inodes on a
  	 * rename.
  	 */
  	time = ubifs_current_time(old_dir);
  	old_inode->i_ctime = time;
  
  	/* We must adjust parent link count when renaming directories */
  	if (is_dir) {
  		if (move) {
  			/*
  			 * @old_dir loses a link because we are moving
  			 * @old_inode to a different directory.
  			 */
  			drop_nlink(old_dir);
  			/*
  			 * @new_dir only gains a link if we are not also
  			 * overwriting an existing directory.
  			 */
  			if (!unlink)
  				inc_nlink(new_dir);
  		} else {
  			/*
  			 * @old_inode is not moving to a different directory,
  			 * but @old_dir still loses a link if we are
  			 * overwriting an existing directory.
  			 */
  			if (unlink)
  				drop_nlink(old_dir);
  		}
  	}
  
  	old_dir->i_size -= old_sz;
  	ubifs_inode(old_dir)->ui_size = old_dir->i_size;
  	old_dir->i_mtime = old_dir->i_ctime = time;
  	new_dir->i_mtime = new_dir->i_ctime = time;
  
  	/*
  	 * And finally, if we unlinked a direntry which happened to have the
  	 * same name as the moved direntry, we have to decrement @i_nlink of
  	 * the unlinked inode and change its ctime.
  	 */
  	if (unlink) {
  		/*
  		 * Directories cannot have hard-links, so if this is a
c43be1085   Artem Bityutskiy   UBIFS: do not use...
1167
  		 * directory, just clear @i_nlink.
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1168
  		 */
c43be1085   Artem Bityutskiy   UBIFS: do not use...
1169
  		saved_nlink = new_inode->i_nlink;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1170
  		if (is_dir)
c43be1085   Artem Bityutskiy   UBIFS: do not use...
1171
1172
  			clear_nlink(new_inode);
  		else
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1173
1174
  			drop_nlink(new_inode);
  		new_inode->i_ctime = time;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
  	} else {
  		new_dir->i_size += new_sz;
  		ubifs_inode(new_dir)->ui_size = new_dir->i_size;
  	}
  
  	/*
  	 * Do not ask 'ubifs_jnl_rename()' to flush write-buffer if @old_inode
  	 * is dirty, because this will be done later on at the end of
  	 * 'ubifs_rename()'.
  	 */
  	if (IS_SYNC(old_inode)) {
  		sync = IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir);
  		if (unlink && IS_SYNC(new_inode))
  			sync = 1;
  	}
9e0a1fff8   Richard Weinberger   ubifs: Implement ...
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
  
  	if (whiteout) {
  		struct ubifs_budget_req wht_req = { .dirtied_ino = 1,
  				.dirtied_ino_d = \
  				ALIGN(ubifs_inode(whiteout)->data_len, 8) };
  
  		err = ubifs_budget_space(c, &wht_req);
  		if (err) {
  			ubifs_release_budget(c, &req);
  			ubifs_release_budget(c, &ino_req);
  			kfree(whiteout_ui->data);
  			whiteout_ui->data_len = 0;
  			iput(whiteout);
  			return err;
  		}
  
  		inc_nlink(whiteout);
  		mark_inode_dirty(whiteout);
  		whiteout->i_state &= ~I_LINKABLE;
  		iput(whiteout);
  	}
  
  	err = ubifs_jnl_rename(c, old_dir, old_dentry, new_dir, new_dentry, whiteout,
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1213
1214
1215
  			       sync);
  	if (err)
  		goto out_cancel;
9e0a1fff8   Richard Weinberger   ubifs: Implement ...
1216
  	unlock_4_inodes(old_dir, new_dir, new_inode, whiteout);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
  	ubifs_release_budget(c, &req);
  
  	mutex_lock(&old_inode_ui->ui_mutex);
  	release = old_inode_ui->dirty;
  	mark_inode_dirty_sync(old_inode);
  	mutex_unlock(&old_inode_ui->ui_mutex);
  
  	if (release)
  		ubifs_release_budget(c, &ino_req);
  	if (IS_SYNC(old_inode))
a9185b41a   Christoph Hellwig   pass writeback_co...
1227
  		err = old_inode->i_sb->s_op->write_inode(old_inode, NULL);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1228
1229
1230
1231
  	return err;
  
  out_cancel:
  	if (unlink) {
c43be1085   Artem Bityutskiy   UBIFS: do not use...
1232
  		set_nlink(new_inode, saved_nlink);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
  	} else {
  		new_dir->i_size -= new_sz;
  		ubifs_inode(new_dir)->ui_size = new_dir->i_size;
  	}
  	old_dir->i_size += old_sz;
  	ubifs_inode(old_dir)->ui_size = old_dir->i_size;
  	if (is_dir) {
  		if (move) {
  			inc_nlink(old_dir);
  			if (!unlink)
  				drop_nlink(new_dir);
  		} else {
  			if (unlink)
  				inc_nlink(old_dir);
  		}
  	}
9e0a1fff8   Richard Weinberger   ubifs: Implement ...
1249
1250
1251
1252
1253
  	if (whiteout) {
  		drop_nlink(whiteout);
  		iput(whiteout);
  	}
  	unlock_4_inodes(old_dir, new_dir, new_inode, whiteout);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1254
1255
1256
1257
  	ubifs_release_budget(c, &ino_req);
  	ubifs_release_budget(c, &req);
  	return err;
  }
9ec64962a   Richard Weinberger   ubifs: Implement ...
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
  static int ubifs_xrename(struct inode *old_dir, struct dentry *old_dentry,
  			struct inode *new_dir, struct dentry *new_dentry)
  {
  	struct ubifs_info *c = old_dir->i_sb->s_fs_info;
  	struct ubifs_budget_req req = { .new_dent = 1, .mod_dent = 1,
  				.dirtied_ino = 2 };
  	int sync = IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir);
  	struct inode *fst_inode = d_inode(old_dentry);
  	struct inode *snd_inode = d_inode(new_dentry);
  	struct timespec time;
  	int err;
  
  	ubifs_assert(fst_inode && snd_inode);
  
  	lock_4_inodes(old_dir, new_dir, NULL, NULL);
  
  	time = ubifs_current_time(old_dir);
  	fst_inode->i_ctime = time;
  	snd_inode->i_ctime = time;
  	old_dir->i_mtime = old_dir->i_ctime = time;
  	new_dir->i_mtime = new_dir->i_ctime = time;
  
  	if (old_dir != new_dir) {
  		if (S_ISDIR(fst_inode->i_mode) && !S_ISDIR(snd_inode->i_mode)) {
  			inc_nlink(new_dir);
  			drop_nlink(old_dir);
  		}
  		else if (!S_ISDIR(fst_inode->i_mode) && S_ISDIR(snd_inode->i_mode)) {
  			drop_nlink(new_dir);
  			inc_nlink(old_dir);
  		}
  	}
  
  	err = ubifs_jnl_xrename(c, old_dir, old_dentry, new_dir, new_dentry,
  				sync);
  
  	unlock_4_inodes(old_dir, new_dir, NULL, NULL);
  	ubifs_release_budget(c, &req);
  
  	return err;
  }
390975ac3   Richard Weinberger   ubifs: Rename ubi...
1299
  static int ubifs_rename(struct inode *old_dir, struct dentry *old_dentry,
9ec64962a   Richard Weinberger   ubifs: Implement ...
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
  			struct inode *new_dir, struct dentry *new_dentry,
  			unsigned int flags)
  {
  	if (flags & ~(RENAME_NOREPLACE | RENAME_WHITEOUT | RENAME_EXCHANGE))
  		return -EINVAL;
  
  	ubifs_assert(inode_is_locked(old_dir));
  	ubifs_assert(inode_is_locked(new_dir));
  
  	if (flags & RENAME_EXCHANGE)
  		return ubifs_xrename(old_dir, old_dentry, new_dir, new_dentry);
390975ac3   Richard Weinberger   ubifs: Rename ubi...
1311
  	return do_rename(old_dir, old_dentry, new_dir, new_dentry, flags);
9ec64962a   Richard Weinberger   ubifs: Implement ...
1312
  }
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1313
1314
1315
1316
  int ubifs_getattr(struct vfsmount *mnt, struct dentry *dentry,
  		  struct kstat *stat)
  {
  	loff_t size;
2b0143b5c   David Howells   VFS: normal files...
1317
  	struct inode *inode = d_inode(dentry);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1318
1319
1320
  	struct ubifs_inode *ui = ubifs_inode(inode);
  
  	mutex_lock(&ui->ui_mutex);
6d42e7e9f   Al Viro   ubifs: use generi...
1321
  	generic_fillattr(inode, stat);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
  	stat->blksize = UBIFS_BLOCK_SIZE;
  	stat->size = ui->ui_size;
  
  	/*
  	 * Unfortunately, the 'stat()' system call was designed for block
  	 * device based file systems, and it is not appropriate for UBIFS,
  	 * because UBIFS does not have notion of "block". For example, it is
  	 * difficult to tell how many block a directory takes - it actually
  	 * takes less than 300 bytes, but we have to round it to block size,
  	 * which introduces large mistake. This makes utilities like 'du' to
  	 * report completely senseless numbers. This is the reason why UBIFS
  	 * goes the same way as JFFS2 - it reports zero blocks for everything
  	 * but regular files, which makes more sense than reporting completely
  	 * wrong sizes.
  	 */
  	if (S_ISREG(inode->i_mode)) {
  		size = ui->xattr_size;
  		size += stat->size;
  		size = ALIGN(size, UBIFS_BLOCK_SIZE);
  		/*
  		 * Note, user-space expects 512-byte blocks count irrespectively
  		 * of what was reported in @stat->size.
  		 */
  		stat->blocks = size >> 9;
  	} else
  		stat->blocks = 0;
  	mutex_unlock(&ui->ui_mutex);
  	return 0;
  }
e8b815663   Artem Bityutskiy   UBIFS: constify o...
1351
  const struct inode_operations ubifs_dir_inode_operations = {
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1352
1353
1354
1355
1356
1357
1358
1359
  	.lookup      = ubifs_lookup,
  	.create      = ubifs_create,
  	.link        = ubifs_link,
  	.symlink     = ubifs_symlink,
  	.unlink      = ubifs_unlink,
  	.mkdir       = ubifs_mkdir,
  	.rmdir       = ubifs_rmdir,
  	.mknod       = ubifs_mknod,
390975ac3   Richard Weinberger   ubifs: Rename ubi...
1360
  	.rename      = ubifs_rename,
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1361
1362
  	.setattr     = ubifs_setattr,
  	.getattr     = ubifs_getattr,
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1363
  	.listxattr   = ubifs_listxattr,
8c1c5f263   Dongsheng Yang   ubifs: introduce ...
1364
1365
1366
  #ifdef CONFIG_UBIFS_ATIME_SUPPORT
  	.update_time = ubifs_update_time,
  #endif
474b93704   Richard Weinberger   ubifs: Implement ...
1367
  	.tmpfile     = ubifs_tmpfile,
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1368
  };
e8b815663   Artem Bityutskiy   UBIFS: constify o...
1369
  const struct file_operations ubifs_dir_operations = {
01122e068   Al Viro   [readdir] convert...
1370
  	.llseek         = generic_file_llseek,
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1371
1372
  	.release        = ubifs_dir_release,
  	.read           = generic_read_dir,
c51da20c4   Al Viro   more trivial ->it...
1373
  	.iterate_shared = ubifs_readdir,
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1374
1375
1376
1377
1378
1379
  	.fsync          = ubifs_fsync,
  	.unlocked_ioctl = ubifs_ioctl,
  #ifdef CONFIG_COMPAT
  	.compat_ioctl   = ubifs_compat_ioctl,
  #endif
  };