Blame view

fs/ubifs/dir.c 42.1 KB
2b27bdcc2   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-only
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
2
3
4
5
6
  /* * This file is part of UBIFS.
   *
   * Copyright (C) 2006-2008 Nokia Corporation.
   * Copyright (C) 2006, 2007 University of Szeged, Hungary
   *
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
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
   * 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 ...
47
  static int inherit_flags(const struct inode *dir, umode_t mode)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
  {
  	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.
   */
d475a5074   Richard Weinberger   ubifs: Add skelet...
76
  struct inode *ubifs_new_inode(struct ubifs_info *c, struct inode *dir,
ad44be5c7   Al Viro   ubifs: propagate ...
77
  			      umode_t mode)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
78
  {
d475a5074   Richard Weinberger   ubifs: Add skelet...
79
  	int err;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
80
81
  	struct inode *inode;
  	struct ubifs_inode *ui;
d475a5074   Richard Weinberger   ubifs: Add skelet...
82
  	bool encrypted = false;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
83
84
85
86
87
88
89
90
91
92
93
  	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...
94
  	inode->i_flags |= S_NOCMTIME;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
95

abf5d08ac   Dmitry Monakhov   ubifs: replace in...
96
  	inode_init_owner(inode, dir, mode);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
97
  	inode->i_mtime = inode->i_atime = inode->i_ctime =
607a11ad9   Deepa Dinamani   fs: ubifs: replac...
98
  			 current_time(inode);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
99
  	inode->i_mapping->nrpages = 0;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
100

4c030fa88   Eric Biggers   ubifs: use fscryp...
101
102
103
104
105
  	err = fscrypt_prepare_new_inode(dir, inode, &encrypted);
  	if (err) {
  		ubifs_err(c, "fscrypt_prepare_new_inode failed: %i", err);
  		goto out_iput;
  	}
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
106
107
108
109
110
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
  	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...
143
  			ubifs_err(c, "out of inode numbers");
4c030fa88   Eric Biggers   ubifs: use fscryp...
144
145
  			err = -EINVAL;
  			goto out_iput;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
146
  		}
1a7e985dd   Sheng Yong   UBIFS: fix output...
147
  		ubifs_warn(c, "running out of inode numbers (current %lu, max %u)",
e84461ad9   Artem Bityutskiy   UBIFS: fix compil...
148
  			   (unsigned long)c->highest_inum, INUM_WATERMARK);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
149
150
151
  	}
  
  	inode->i_ino = ++c->highest_inum;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
152
153
154
155
156
157
158
159
160
  	/*
  	 * 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);
d475a5074   Richard Weinberger   ubifs: Add skelet...
161
162
  
  	if (encrypted) {
4c030fa88   Eric Biggers   ubifs: use fscryp...
163
  		err = fscrypt_set_context(inode, NULL);
d475a5074   Richard Weinberger   ubifs: Add skelet...
164
  		if (err) {
4c030fa88   Eric Biggers   ubifs: use fscryp...
165
166
  			ubifs_err(c, "fscrypt_set_context failed: %i", err);
  			goto out_iput;
d475a5074   Richard Weinberger   ubifs: Add skelet...
167
168
  		}
  	}
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
169
  	return inode;
4c030fa88   Eric Biggers   ubifs: use fscryp...
170
171
172
173
174
  
  out_iput:
  	make_bad_inode(inode);
  	iput(inode);
  	return ERR_PTR(err);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
175
  }
bb2615d4d   Artem Bityutskiy   UBIFS: amend debu...
176
177
  static int dbg_check_name(const struct ubifs_info *c,
  			  const struct ubifs_dent_node *dent,
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
178
  			  const struct fscrypt_name *nm)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
179
  {
2b1844a8c   Artem Bityutskiy   UBIFS: introduce ...
180
  	if (!dbg_is_chk_gen(c))
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
181
  		return 0;
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
182
  	if (le16_to_cpu(dent->nlen) != fname_len(nm))
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
183
  		return -EINVAL;
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
184
  	if (memcmp(dent->name, fname_name(nm), fname_len(nm)))
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
185
186
187
  		return -EINVAL;
  	return 0;
  }
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
188
  static struct dentry *ubifs_lookup(struct inode *dir, struct dentry *dentry,
00cd8dd3b   Al Viro   stop passing name...
189
  				   unsigned int flags)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
190
191
192
193
  {
  	int err;
  	union ubifs_key key;
  	struct inode *inode = NULL;
191ac107f   Al Viro   ubifs_lookup: use...
194
  	struct ubifs_dent_node *dent = NULL;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
195
  	struct ubifs_info *c = dir->i_sb->s_fs_info;
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
196
  	struct fscrypt_name nm;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
197

4cb2a01d8   Al Viro   ubifs: switch to %pd
198
  	dbg_gen("'%pd' in dir ino %lu", dentry, dir->i_ino);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
199

b01531db6   Eric Biggers   fscrypt: fix race...
200
201
202
  	err = fscrypt_prepare_lookup(dir, dentry, &nm);
  	if (err == -ENOENT)
  		return d_splice_alias(NULL, dentry);
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
203
204
205
206
  	if (err)
  		return ERR_PTR(err);
  
  	if (fname_len(&nm) > UBIFS_MAX_NLEN) {
191ac107f   Al Viro   ubifs_lookup: use...
207
208
  		inode = ERR_PTR(-ENAMETOOLONG);
  		goto done;
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
209
  	}
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
210
211
  
  	dent = kmalloc(UBIFS_MAX_DENT_NODE_SZ, GFP_NOFS);
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
212
  	if (!dent) {
191ac107f   Al Viro   ubifs_lookup: use...
213
214
  		inode = ERR_PTR(-ENOMEM);
  		goto done;
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
215
  	}
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
216

aec992aab   Eric Biggers   ubifs: allow both...
217
  	if (fname_name(&nm) == NULL) {
f0d07a98a   Eric Biggers   ubifs: don't trig...
218
219
  		if (nm.hash & ~UBIFS_S_KEY_HASH_MASK)
  			goto done; /* ENOENT */
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
220
  		dent_key_init_hash(c, &key, dir->i_ino, nm.hash);
528e3d178   Richard Weinberger   ubifs: Add full h...
221
  		err = ubifs_tnc_lookup_dh(c, &key, dent, nm.minor_hash);
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
222
223
224
225
  	} else {
  		dent_key_init(c, &key, dir->i_ino, &nm);
  		err = ubifs_tnc_lookup_nm(c, &key, dent, &nm);
  	}
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
226

1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
227
  	if (err) {
191ac107f   Al Viro   ubifs_lookup: use...
228
  		if (err == -ENOENT)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
229
  			dbg_gen("not found");
191ac107f   Al Viro   ubifs_lookup: use...
230
231
232
  		else
  			inode = ERR_PTR(err);
  		goto done;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
233
  	}
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
234
  	if (dbg_check_name(c, dent, &nm)) {
191ac107f   Al Viro   ubifs_lookup: use...
235
236
  		inode = ERR_PTR(-EINVAL);
  		goto done;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
237
238
239
240
241
242
243
244
245
  	}
  
  	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...
246
  		ubifs_err(c, "dead directory entry '%pd', error %d",
4cb2a01d8   Al Viro   ubifs: switch to %pd
247
  			  dentry, err);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
248
  		ubifs_ro_mode(c, err);
191ac107f   Al Viro   ubifs_lookup: use...
249
  		goto done;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
250
  	}
50d9fad73   Eric Biggers   ubifs: use IS_ENC...
251
  	if (IS_ENCRYPTED(dir) &&
413d5a9ed   Eric Biggers   ubifs: check for ...
252
253
254
255
  	    (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) &&
  	    !fscrypt_has_permitted_context(dir, inode)) {
  		ubifs_warn(c, "Inconsistent encryption contexts: %lu/%lu",
  			   dir->i_ino, inode->i_ino);
191ac107f   Al Viro   ubifs_lookup: use...
256
257
  		iput(inode);
  		inode = ERR_PTR(-EPERM);
413d5a9ed   Eric Biggers   ubifs: check for ...
258
  	}
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
259
260
  done:
  	kfree(dent);
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
261
  	fscrypt_free_filename(&nm);
191ac107f   Al Viro   ubifs_lookup: use...
262
  	return d_splice_alias(inode, dentry);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
263
  }
456fcfca6   Eric Biggers   ubifs: prevent cr...
264
265
266
267
268
269
270
271
  static int ubifs_prepare_create(struct inode *dir, struct dentry *dentry,
  				struct fscrypt_name *nm)
  {
  	if (fscrypt_is_nokey_name(dentry))
  		return -ENOKEY;
  
  	return fscrypt_setup_filename(dir, &dentry->d_name, 0, nm);
  }
4acdaf27e   Al Viro   switch ->create()...
272
  static int ubifs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
ebfc3b49a   Al Viro   don't pass nameid...
273
  			bool excl)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
274
275
276
  {
  	struct inode *inode;
  	struct ubifs_info *c = dir->i_sb->s_fs_info;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
277
278
279
  	struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1,
  					.dirtied_ino = 1 };
  	struct ubifs_inode *dir_ui = ubifs_inode(dir);
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
280
281
  	struct fscrypt_name nm;
  	int err, sz_change;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
282
283
284
285
286
  
  	/*
  	 * Budget request settings: new inode, new direntry, changing the
  	 * parent directory inode.
  	 */
4cb2a01d8   Al Viro   ubifs: switch to %pd
287
288
  	dbg_gen("dent '%pd', mode %#hx in dir ino %lu",
  		dentry, mode, dir->i_ino);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
289
290
291
292
  
  	err = ubifs_budget_space(c, &req);
  	if (err)
  		return err;
456fcfca6   Eric Biggers   ubifs: prevent cr...
293
  	err = ubifs_prepare_create(dir, dentry, &nm);
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
294
295
296
297
  	if (err)
  		goto out_budg;
  
  	sz_change = CALC_DENT_SIZE(fname_len(&nm));
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
298
299
300
  	inode = ubifs_new_inode(c, dir, mode);
  	if (IS_ERR(inode)) {
  		err = PTR_ERR(inode);
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
301
  		goto out_fname;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
302
  	}
d7f0b70d3   Subodh Nijsure   UBIFS: Add securi...
303
304
  	err = ubifs_init_security(dir, inode, &dentry->d_name);
  	if (err)
9401a795c   Taesoo Kim   UBIFS: fix incorr...
305
  		goto out_inode;
d7f0b70d3   Subodh Nijsure   UBIFS: Add securi...
306

1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
307
308
309
310
  	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;
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
311
  	err = ubifs_jnl_update(c, dir, &nm, inode, 0, 0);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
312
313
314
315
316
  	if (err)
  		goto out_cancel;
  	mutex_unlock(&dir_ui->ui_mutex);
  
  	ubifs_release_budget(c, &req);
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
317
  	fscrypt_free_filename(&nm);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
318
319
320
321
322
323
324
325
  	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...
326
  out_inode:
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
327
328
  	make_bad_inode(inode);
  	iput(inode);
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
329
330
  out_fname:
  	fscrypt_free_filename(&nm);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
331
332
  out_budg:
  	ubifs_release_budget(c, &req);
235c362bd   Sheng Yong   UBIFS: extend deb...
333
  	ubifs_err(c, "cannot create regular file, error %d", err);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
334
335
  	return err;
  }
9e0a1fff8   Richard Weinberger   ubifs: Implement ...
336
337
  static int do_tmpfile(struct inode *dir, struct dentry *dentry,
  		      umode_t mode, struct inode **whiteout)
474b93704   Richard Weinberger   ubifs: Implement ...
338
339
340
341
342
343
344
  {
  	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;
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
345
  	struct fscrypt_name nm;
474b93704   Richard Weinberger   ubifs: Implement ...
346
347
348
349
350
351
352
353
  
  	/*
  	 * 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);
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
354
  	err = fscrypt_setup_filename(dir, &dentry->d_name, 0, &nm);
474b93704   Richard Weinberger   ubifs: Implement ...
355
356
  	if (err)
  		return err;
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
357
358
359
360
361
  	err = ubifs_budget_space(c, &req);
  	if (err) {
  		fscrypt_free_filename(&nm);
  		return err;
  	}
474b93704   Richard Weinberger   ubifs: Implement ...
362
363
364
  	err = ubifs_budget_space(c, &ino_req);
  	if (err) {
  		ubifs_release_budget(c, &req);
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
365
  		fscrypt_free_filename(&nm);
474b93704   Richard Weinberger   ubifs: Implement ...
366
367
368
369
370
371
372
373
374
  		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 ...
375
376
  	if (whiteout) {
  		init_special_inode(inode, inode->i_mode, WHITEOUT_DEV);
6eb61d587   Richard Weinberger   ubifs: Pass struc...
377
  		ubifs_assert(c, inode->i_op == &ubifs_file_inode_operations);
9e0a1fff8   Richard Weinberger   ubifs: Implement ...
378
  	}
474b93704   Richard Weinberger   ubifs: Implement ...
379
380
381
382
383
384
  	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 ...
385
386
387
388
389
390
391
392
  
  	if (whiteout) {
  		mark_inode_dirty(inode);
  		drop_nlink(inode);
  		*whiteout = inode;
  	} else {
  		d_tmpfile(dentry, inode);
  	}
6eb61d587   Richard Weinberger   ubifs: Pass struc...
393
  	ubifs_assert(c, ui->dirty);
9e0a1fff8   Richard Weinberger   ubifs: Implement ...
394

474b93704   Richard Weinberger   ubifs: Implement ...
395
396
397
398
  	instantiated = 1;
  	mutex_unlock(&ui->ui_mutex);
  
  	mutex_lock(&dir_ui->ui_mutex);
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
399
  	err = ubifs_jnl_update(c, dir, &nm, inode, 1, 0);
474b93704   Richard Weinberger   ubifs: Implement ...
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
  	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);
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
418
  	fscrypt_free_filename(&nm);
474b93704   Richard Weinberger   ubifs: Implement ...
419
420
421
  	ubifs_err(c, "cannot create temporary file, error %d", err);
  	return err;
  }
9e0a1fff8   Richard Weinberger   ubifs: Implement ...
422
423
424
425
426
  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...
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
  /**
   * 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...
474
  static int ubifs_readdir(struct file *file, struct dir_context *ctx)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
475
  {
ba75d570b   Richard Weinberger   ubifs: Initialize...
476
  	int fstr_real_len = 0, err = 0;
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
477
478
  	struct fscrypt_name nm;
  	struct fscrypt_str fstr = {0};
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
479
480
  	union ubifs_key key;
  	struct ubifs_dent_node *dent;
496ad9aa8   Al Viro   new helper: file_...
481
  	struct inode *dir = file_inode(file);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
482
  	struct ubifs_info *c = dir->i_sb->s_fs_info;
50d9fad73   Eric Biggers   ubifs: use IS_ENC...
483
  	bool encrypted = IS_ENCRYPTED(dir);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
484

01122e068   Al Viro   [readdir] convert...
485
  	dbg_gen("dir ino %lu, f_pos %#llx", dir->i_ino, ctx->pos);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
486

01122e068   Al Viro   [readdir] convert...
487
  	if (ctx->pos > UBIFS_S_KEY_HASH_MASK || ctx->pos == 2)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
488
489
490
491
492
  		/*
  		 * The directory was seek'ed to a senseless position or there
  		 * are no more entries.
  		 */
  		return 0;
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
493
494
  	if (encrypted) {
  		err = fscrypt_get_encryption_info(dir);
3b1ada55b   Eric Biggers   fscrypt: don't ch...
495
  		if (err)
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
496
  			return err;
8b10fe689   Jeff Layton   fscrypt: drop unu...
497
  		err = fscrypt_fname_alloc_buffer(UBIFS_MAX_NLEN, &fstr);
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
498
499
500
501
502
  		if (err)
  			return err;
  
  		fstr_real_len = fstr.len;
  	}
605c912bb   Artem Bityutskiy   UBIFS: fix a horr...
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
  	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...
520
  	/* File positions 0 and 1 correspond to "." and ".." */
01122e068   Al Viro   [readdir] convert...
521
  	if (ctx->pos < 2) {
6eb61d587   Richard Weinberger   ubifs: Pass struc...
522
  		ubifs_assert(c, !file->private_data);
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
523
524
525
  		if (!dir_emit_dots(file, ctx)) {
  			if (encrypted)
  				fscrypt_fname_free_buffer(&fstr);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
526
  			return 0;
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
527
  		}
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
528
529
530
  
  		/* Find the first entry in TNC and save it */
  		lowest_dent_key(c, &key, dir->i_ino);
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
531
  		fname_len(&nm) = 0;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
532
533
534
535
536
  		dent = ubifs_tnc_next_ent(c, &key, &nm);
  		if (IS_ERR(dent)) {
  			err = PTR_ERR(dent);
  			goto out;
  		}
01122e068   Al Viro   [readdir] convert...
537
  		ctx->pos = key_hash_flash(c, &dent->key);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
538
539
540
541
542
543
544
  		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...
545
  		 * Find the entry corresponding to @ctx->pos or the closest one.
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
546
  		 */
01122e068   Al Viro   [readdir] convert...
547
  		dent_key_init_hash(c, &key, dir->i_ino, ctx->pos);
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
548
  		fname_len(&nm) = 0;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
549
550
551
552
553
  		dent = ubifs_tnc_next_ent(c, &key, &nm);
  		if (IS_ERR(dent)) {
  			err = PTR_ERR(dent);
  			goto out;
  		}
01122e068   Al Viro   [readdir] convert...
554
  		ctx->pos = key_hash_flash(c, &dent->key);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
555
556
557
558
  		file->private_data = dent;
  	}
  
  	while (1) {
b20e2d999   Hyunchul Lee   ubifs: Remove fil...
559
560
  		dbg_gen("ino %llu, new f_pos %#x",
  			(unsigned long long)le64_to_cpu(dent->inum),
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
561
  			key_hash_flash(c, &dent->key));
6eb61d587   Richard Weinberger   ubifs: Pass struc...
562
  		ubifs_assert(c, le64_to_cpu(dent->ch.sqnum) >
0ecb9529a   Harvey Harrison   UBIFS: endian han...
563
  			     ubifs_inode(dir)->creat_sqnum);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
564

f4f61d2cc   Richard Weinberger   ubifs: Implement ...
565
566
567
568
569
  		fname_len(&nm) = le16_to_cpu(dent->nlen);
  		fname_name(&nm) = dent->name;
  
  		if (encrypted) {
  			fstr.len = fstr_real_len;
528e3d178   Richard Weinberger   ubifs: Add full h...
570
571
572
573
  			err = fscrypt_fname_disk_to_usr(dir, key_hash_flash(c,
  							&dent->key),
  							le32_to_cpu(dent->cookie),
  							&nm.disk_name, &fstr);
ca7f85be8   Richard Weinberger   ubifs: Add suppor...
574
  			if (err)
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
575
576
577
578
579
580
581
  				goto out;
  		} else {
  			fstr.len = fname_len(&nm);
  			fstr.name = fname_name(&nm);
  		}
  
  		if (!dir_emit(ctx, fstr.name, fstr.len,
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
582
  			       le64_to_cpu(dent->inum),
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
583
584
585
  			       vfs_dent_type(dent->type))) {
  			if (encrypted)
  				fscrypt_fname_free_buffer(&fstr);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
586
  			return 0;
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
587
  		}
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
588
589
590
  
  		/* Switch to the next entry */
  		key_read(c, &dent->key, &key);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
591
592
593
594
595
596
597
  		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...
598
  		ctx->pos = key_hash_flash(c, &dent->key);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
599
600
601
602
603
  		file->private_data = dent;
  		cond_resched();
  	}
  
  out:
aeeb14f76   Richard Weinberger   UBIFS: Fix possib...
604
605
  	kfree(file->private_data);
  	file->private_data = NULL;
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
606
607
  	if (encrypted)
  		fscrypt_fname_free_buffer(&fstr);
c83ed4c9d   Richard Weinberger   ubifs: Abort read...
608
  	if (err != -ENOENT)
235c362bd   Sheng Yong   UBIFS: extend deb...
609
  		ubifs_err(c, "cannot find next direntry, error %d", err);
a00052a29   Richard Weinberger   ubifs: Fix regres...
610
611
612
613
614
615
616
  	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...
617

605c912bb   Artem Bityutskiy   UBIFS: fix a horr...
618
  	/* 2 is a special value indicating that there are no more direntries */
01122e068   Al Viro   [readdir] convert...
619
  	ctx->pos = 2;
c83ed4c9d   Richard Weinberger   ubifs: Abort read...
620
  	return err;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
621
  }
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
622
623
624
625
626
627
628
629
630
  /* 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...
631
   * lock_2_inodes - a wrapper for locking two UBIFS inodes.
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
632
633
   * @inode1: first inode
   * @inode2: second inode
82c1593ca   Artem Bityutskiy   UBIFS: simplify l...
634
635
636
637
   *
   * 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...
638
639
640
   */
  static void lock_2_inodes(struct inode *inode1, struct inode *inode2)
  {
82c1593ca   Artem Bityutskiy   UBIFS: simplify l...
641
642
  	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...
643
644
645
  }
  
  /**
82c1593ca   Artem Bityutskiy   UBIFS: simplify l...
646
   * unlock_2_inodes - a wrapper for unlocking two UBIFS inodes.
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
647
648
649
650
651
   * @inode1: first inode
   * @inode2: second inode
   */
  static void unlock_2_inodes(struct inode *inode1, struct inode *inode2)
  {
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
652
  	mutex_unlock(&ubifs_inode(inode2)->ui_mutex);
82c1593ca   Artem Bityutskiy   UBIFS: simplify l...
653
  	mutex_unlock(&ubifs_inode(inode1)->ui_mutex);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
654
655
656
657
658
659
  }
  
  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...
660
  	struct inode *inode = d_inode(old_dentry);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
661
662
663
664
  	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...
665
  				.dirtied_ino_d = ALIGN(ui->data_len, 8) };
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
666
  	struct fscrypt_name nm;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
667
668
669
670
671
  
  	/*
  	 * Budget request settings: new direntry, changing the target inode,
  	 * changing the parent inode.
  	 */
4cb2a01d8   Al Viro   ubifs: switch to %pd
672
673
  	dbg_gen("dent '%pd' to ino %lu (nlink %d) in dir ino %lu",
  		dentry, inode->i_ino,
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
674
  		inode->i_nlink, dir->i_ino);
6eb61d587   Richard Weinberger   ubifs: Pass struc...
675
676
  	ubifs_assert(c, inode_is_locked(dir));
  	ubifs_assert(c, inode_is_locked(inode));
8b3884a84   Hunter Adrian   UBIFS: return err...
677

5653878c8   Eric Biggers   ubifs: switch to ...
678
679
680
  	err = fscrypt_prepare_link(old_dentry, dir, dentry);
  	if (err)
  		return err;
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
681
682
  
  	err = fscrypt_setup_filename(dir, &dentry->d_name, 0, &nm);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
683
684
  	if (err)
  		return err;
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
685
686
687
  	err = dbg_check_synced_i_size(c, inode);
  	if (err)
  		goto out_fname;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
688
689
  	err = ubifs_budget_space(c, &req);
  	if (err)
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
690
  		goto out_fname;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
691
692
  
  	lock_2_inodes(dir, inode);
32fe905c1   Richard Weinberger   ubifs: Fix O_TMPF...
693
694
695
696
  
  	/* 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...
697
  	inc_nlink(inode);
7de9c6ee3   Al Viro   new helper: ihold()
698
  	ihold(inode);
607a11ad9   Deepa Dinamani   fs: ubifs: replac...
699
  	inode->i_ctime = current_time(inode);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
700
701
702
  	dir->i_size += sz_change;
  	dir_ui->ui_size = dir->i_size;
  	dir->i_mtime = dir->i_ctime = inode->i_ctime;
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
703
  	err = ubifs_jnl_update(c, dir, &nm, inode, 0, 0);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
704
705
706
707
708
709
  	if (err)
  		goto out_cancel;
  	unlock_2_inodes(dir, inode);
  
  	ubifs_release_budget(c, &req);
  	d_instantiate(dentry, inode);
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
710
  	fscrypt_free_filename(&nm);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
711
712
713
714
715
716
  	return 0;
  
  out_cancel:
  	dir->i_size -= sz_change;
  	dir_ui->ui_size = dir->i_size;
  	drop_nlink(inode);
32fe905c1   Richard Weinberger   ubifs: Fix O_TMPF...
717
718
  	if (inode->i_nlink == 0)
  		ubifs_add_orphan(c, inode->i_ino);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
719
720
721
  	unlock_2_inodes(dir, inode);
  	ubifs_release_budget(c, &req);
  	iput(inode);
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
722
723
  out_fname:
  	fscrypt_free_filename(&nm);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
724
725
726
727
728
729
  	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...
730
  	struct inode *inode = d_inode(dentry);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
731
  	struct ubifs_inode *dir_ui = ubifs_inode(dir);
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
732
  	int err, sz_change, budgeted = 1;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
733
  	struct ubifs_budget_req req = { .mod_dent = 1, .dirtied_ino = 2 };
c43be1085   Artem Bityutskiy   UBIFS: do not use...
734
  	unsigned int saved_nlink = inode->i_nlink;
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
735
  	struct fscrypt_name nm;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
736
737
738
739
740
741
742
  
  	/*
  	 * 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
743
744
  	dbg_gen("dent '%pd' from ino %lu (nlink %d) in dir ino %lu",
  		dentry, inode->i_ino,
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
745
  		inode->i_nlink, dir->i_ino);
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
746

f4f61d2cc   Richard Weinberger   ubifs: Implement ...
747
748
749
  	err = fscrypt_setup_filename(dir, &dentry->d_name, 1, &nm);
  	if (err)
  		return err;
9ca2d7326   Richard Weinberger   ubifs: Limit numb...
750
751
752
  	err = ubifs_purge_xattrs(inode);
  	if (err)
  		return err;
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
753
  	sz_change = CALC_DENT_SIZE(fname_len(&nm));
6eb61d587   Richard Weinberger   ubifs: Pass struc...
754
755
  	ubifs_assert(c, inode_is_locked(dir));
  	ubifs_assert(c, inode_is_locked(inode));
d808efb40   Artem Bityutskiy   UBIFS: amend debu...
756
  	err = dbg_check_synced_i_size(c, inode);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
757
  	if (err)
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
758
  		goto out_fname;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
759
760
761
762
  
  	err = ubifs_budget_space(c, &req);
  	if (err) {
  		if (err != -ENOSPC)
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
763
  			goto out_fname;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
764
765
766
767
  		budgeted = 0;
  	}
  
  	lock_2_inodes(dir, inode);
607a11ad9   Deepa Dinamani   fs: ubifs: replac...
768
  	inode->i_ctime = current_time(dir);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
769
770
771
772
  	drop_nlink(inode);
  	dir->i_size -= sz_change;
  	dir_ui->ui_size = dir->i_size;
  	dir->i_mtime = dir->i_ctime = inode->i_ctime;
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
773
  	err = ubifs_jnl_update(c, dir, &nm, inode, 1, 0);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
774
775
776
777
778
779
780
781
  	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 ...
782
  		c->bi.nospace = c->bi.nospace_rp = 0;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
783
784
  		smp_wmb();
  	}
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
785
  	fscrypt_free_filename(&nm);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
786
787
788
789
790
  	return 0;
  
  out_cancel:
  	dir->i_size += sz_change;
  	dir_ui->ui_size = dir->i_size;
c43be1085   Artem Bityutskiy   UBIFS: do not use...
791
  	set_nlink(inode, saved_nlink);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
792
793
794
  	unlock_2_inodes(dir, inode);
  	if (budgeted)
  		ubifs_release_budget(c, &req);
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
795
796
  out_fname:
  	fscrypt_free_filename(&nm);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
797
798
799
800
801
  	return err;
  }
  
  /**
   * check_dir_empty - check if a directory is empty or not.
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
802
803
804
805
806
807
   * @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.
   */
f6337d842   Richard Weinberger   ubifs: Export ubi...
808
  int ubifs_check_dir_empty(struct inode *dir)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
809
  {
f6337d842   Richard Weinberger   ubifs: Export ubi...
810
  	struct ubifs_info *c = dir->i_sb->s_fs_info;
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
811
  	struct fscrypt_name nm = { 0 };
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
  	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...
832
  	struct inode *inode = d_inode(dentry);
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
833
  	int err, sz_change, budgeted = 1;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
834
835
  	struct ubifs_inode *dir_ui = ubifs_inode(dir);
  	struct ubifs_budget_req req = { .mod_dent = 1, .dirtied_ino = 2 };
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
836
  	struct fscrypt_name nm;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
837
838
839
840
841
842
  
  	/*
  	 * 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
843
844
  	dbg_gen("directory '%pd', ino %lu in dir ino %lu", dentry,
  		inode->i_ino, dir->i_ino);
6eb61d587   Richard Weinberger   ubifs: Pass struc...
845
846
  	ubifs_assert(c, inode_is_locked(dir));
  	ubifs_assert(c, inode_is_locked(inode));
f6337d842   Richard Weinberger   ubifs: Export ubi...
847
  	err = ubifs_check_dir_empty(d_inode(dentry));
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
848
849
  	if (err)
  		return err;
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
850
851
852
  	err = fscrypt_setup_filename(dir, &dentry->d_name, 1, &nm);
  	if (err)
  		return err;
9ca2d7326   Richard Weinberger   ubifs: Limit numb...
853
854
855
  	err = ubifs_purge_xattrs(inode);
  	if (err)
  		return err;
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
856
  	sz_change = CALC_DENT_SIZE(fname_len(&nm));
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
857
858
859
  	err = ubifs_budget_space(c, &req);
  	if (err) {
  		if (err != -ENOSPC)
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
860
  			goto out_fname;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
861
862
863
864
  		budgeted = 0;
  	}
  
  	lock_2_inodes(dir, inode);
607a11ad9   Deepa Dinamani   fs: ubifs: replac...
865
  	inode->i_ctime = current_time(dir);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
866
867
868
869
870
  	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;
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
871
  	err = ubifs_jnl_update(c, dir, &nm, inode, 1, 0);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
872
873
874
875
876
877
878
879
  	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 ...
880
  		c->bi.nospace = c->bi.nospace_rp = 0;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
881
882
  		smp_wmb();
  	}
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
883
  	fscrypt_free_filename(&nm);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
884
885
886
887
888
889
  	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...
890
  	set_nlink(inode, 2);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
891
892
893
  	unlock_2_inodes(dir, inode);
  	if (budgeted)
  		ubifs_release_budget(c, &req);
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
894
895
  out_fname:
  	fscrypt_free_filename(&nm);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
896
897
  	return err;
  }
18bb1db3e   Al Viro   switch vfs_mkdir(...
898
  static int ubifs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
899
900
901
902
  {
  	struct inode *inode;
  	struct ubifs_inode *dir_ui = ubifs_inode(dir);
  	struct ubifs_info *c = dir->i_sb->s_fs_info;
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
903
  	int err, sz_change;
182854b46   Artem Bityutskiy   UBIFS: fix budget...
904
  	struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1 };
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
905
  	struct fscrypt_name nm;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
906
907
908
909
910
  
  	/*
  	 * Budget request settings: new inode, new direntry and changing parent
  	 * directory inode.
  	 */
4cb2a01d8   Al Viro   ubifs: switch to %pd
911
912
  	dbg_gen("dent '%pd', mode %#hx in dir ino %lu",
  		dentry, mode, dir->i_ino);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
913
914
915
916
  
  	err = ubifs_budget_space(c, &req);
  	if (err)
  		return err;
456fcfca6   Eric Biggers   ubifs: prevent cr...
917
  	err = ubifs_prepare_create(dir, dentry, &nm);
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
918
919
920
921
  	if (err)
  		goto out_budg;
  
  	sz_change = CALC_DENT_SIZE(fname_len(&nm));
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
922
923
924
  	inode = ubifs_new_inode(c, dir, S_IFDIR | mode);
  	if (IS_ERR(inode)) {
  		err = PTR_ERR(inode);
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
925
  		goto out_fname;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
926
  	}
d7f0b70d3   Subodh Nijsure   UBIFS: Add securi...
927
928
  	err = ubifs_init_security(dir, inode, &dentry->d_name);
  	if (err)
9401a795c   Taesoo Kim   UBIFS: fix incorr...
929
  		goto out_inode;
d7f0b70d3   Subodh Nijsure   UBIFS: Add securi...
930

1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
931
932
933
934
935
936
937
  	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;
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
938
  	err = ubifs_jnl_update(c, dir, &nm, inode, 0, 0);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
939
  	if (err) {
235c362bd   Sheng Yong   UBIFS: extend deb...
940
  		ubifs_err(c, "cannot create directory, error %d", err);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
941
942
943
944
945
946
  		goto out_cancel;
  	}
  	mutex_unlock(&dir_ui->ui_mutex);
  
  	ubifs_release_budget(c, &req);
  	d_instantiate(dentry, inode);
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
947
  	fscrypt_free_filename(&nm);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
948
949
950
951
952
953
954
  	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...
955
  out_inode:
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
956
957
  	make_bad_inode(inode);
  	iput(inode);
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
958
959
  out_fname:
  	fscrypt_free_filename(&nm);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
960
961
962
963
964
965
  out_budg:
  	ubifs_release_budget(c, &req);
  	return err;
  }
  
  static int ubifs_mknod(struct inode *dir, struct dentry *dentry,
1a67aafb5   Al Viro   switch ->mknod() ...
966
  		       umode_t mode, dev_t rdev)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
967
968
969
970
971
972
  {
  	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;
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
973
  	int sz_change;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
974
975
  	int err, devlen = 0;
  	struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1,
dab4b4d2f   Artem Bityutskiy   UBIFS: align inod...
976
  					.dirtied_ino = 1 };
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
977
  	struct fscrypt_name nm;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
978
979
980
981
982
  
  	/*
  	 * Budget request settings: new inode, new direntry and changing parent
  	 * directory inode.
  	 */
4cb2a01d8   Al Viro   ubifs: switch to %pd
983
  	dbg_gen("dent '%pd' in dir ino %lu", dentry, dir->i_ino);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
984

1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
985
986
987
988
989
990
  	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);
  	}
4d35ca4f7   Hyunchul Lee   ubifs: Fix inode ...
991
  	req.new_ino_d = ALIGN(devlen, 8);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
992
993
994
995
996
  	err = ubifs_budget_space(c, &req);
  	if (err) {
  		kfree(dev);
  		return err;
  	}
456fcfca6   Eric Biggers   ubifs: prevent cr...
997
  	err = ubifs_prepare_create(dir, dentry, &nm);
63ed65736   Richard Weinberger   ubifs: Fix memory...
998
999
  	if (err) {
  		kfree(dev);
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
1000
  		goto out_budg;
63ed65736   Richard Weinberger   ubifs: Fix memory...
1001
  	}
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
1002
1003
  
  	sz_change = CALC_DENT_SIZE(fname_len(&nm));
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1004
1005
1006
1007
  	inode = ubifs_new_inode(c, dir, mode);
  	if (IS_ERR(inode)) {
  		kfree(dev);
  		err = PTR_ERR(inode);
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
1008
  		goto out_fname;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1009
1010
1011
1012
1013
1014
1015
  	}
  
  	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...
1016
1017
  	err = ubifs_init_security(dir, inode, &dentry->d_name);
  	if (err)
9401a795c   Taesoo Kim   UBIFS: fix incorr...
1018
  		goto out_inode;
d7f0b70d3   Subodh Nijsure   UBIFS: Add securi...
1019

1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1020
1021
1022
1023
  	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;
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
1024
  	err = ubifs_jnl_update(c, dir, &nm, inode, 0, 0);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1025
1026
1027
1028
1029
1030
1031
  	if (err)
  		goto out_cancel;
  	mutex_unlock(&dir_ui->ui_mutex);
  
  	ubifs_release_budget(c, &req);
  	insert_inode_hash(inode);
  	d_instantiate(dentry, inode);
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
1032
  	fscrypt_free_filename(&nm);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1033
1034
1035
1036
1037
1038
  	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...
1039
  out_inode:
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1040
1041
  	make_bad_inode(inode);
  	iput(inode);
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
1042
1043
  out_fname:
  	fscrypt_free_filename(&nm);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
  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;
00ee8b601   Richard Weinberger   ubifs: Fix direct...
1056
  	int err, sz_change, len = strlen(symname);
0e4dda290   Eric Biggers   ubifs: switch to ...
1057
  	struct fscrypt_str disk_link;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1058
  	struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1,
dab4b4d2f   Artem Bityutskiy   UBIFS: align inod...
1059
1060
  					.new_ino_d = ALIGN(len, 8),
  					.dirtied_ino = 1 };
ca7f85be8   Richard Weinberger   ubifs: Add suppor...
1061
  	struct fscrypt_name nm;
0e4dda290   Eric Biggers   ubifs: switch to ...
1062
1063
  	dbg_gen("dent '%pd', target '%s' in dir ino %lu", dentry,
  		symname, dir->i_ino);
ca7f85be8   Richard Weinberger   ubifs: Add suppor...
1064

0e4dda290   Eric Biggers   ubifs: switch to ...
1065
1066
1067
1068
  	err = fscrypt_prepare_symlink(dir, symname, len, UBIFS_MAX_INO_DATA,
  				      &disk_link);
  	if (err)
  		return err;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1069
1070
1071
1072
1073
  
  	/*
  	 * Budget request settings: new inode, new direntry and changing parent
  	 * directory inode.
  	 */
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1074
1075
1076
  	err = ubifs_budget_space(c, &req);
  	if (err)
  		return err;
456fcfca6   Eric Biggers   ubifs: prevent cr...
1077
  	err = ubifs_prepare_create(dir, dentry, &nm);
ca7f85be8   Richard Weinberger   ubifs: Add suppor...
1078
1079
  	if (err)
  		goto out_budg;
00ee8b601   Richard Weinberger   ubifs: Fix direct...
1080
  	sz_change = CALC_DENT_SIZE(fname_len(&nm));
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1081
1082
1083
  	inode = ubifs_new_inode(c, dir, S_IFLNK | S_IRWXUGO);
  	if (IS_ERR(inode)) {
  		err = PTR_ERR(inode);
ca7f85be8   Richard Weinberger   ubifs: Add suppor...
1084
  		goto out_fname;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1085
1086
1087
  	}
  
  	ui = ubifs_inode(inode);
ca7f85be8   Richard Weinberger   ubifs: Add suppor...
1088
  	ui->data = kmalloc(disk_link.len, GFP_NOFS);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1089
1090
1091
1092
  	if (!ui->data) {
  		err = -ENOMEM;
  		goto out_inode;
  	}
0e4dda290   Eric Biggers   ubifs: switch to ...
1093
1094
1095
  	if (IS_ENCRYPTED(inode)) {
  		disk_link.name = ui->data; /* encrypt directly into ui->data */
  		err = fscrypt_encrypt_symlink(inode, symname, len, &disk_link);
6b46d4441   Eric Biggers   ubifs: free the e...
1096
  		if (err)
ca7f85be8   Richard Weinberger   ubifs: Add suppor...
1097
  			goto out_inode;
ca7f85be8   Richard Weinberger   ubifs: Add suppor...
1098
  	} else {
0e4dda290   Eric Biggers   ubifs: switch to ...
1099
  		memcpy(ui->data, disk_link.name, disk_link.len);
ca7f85be8   Richard Weinberger   ubifs: Add suppor...
1100
1101
  		inode->i_link = ui->data;
  	}
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1102
1103
1104
  	/*
  	 * 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,
0e4dda290   Eric Biggers   ubifs: switch to ...
1105
  	 * data length is @disk_link.len - 1, not @disk_link.len.
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1106
  	 */
ca7f85be8   Richard Weinberger   ubifs: Add suppor...
1107
1108
  	ui->data_len = disk_link.len - 1;
  	inode->i_size = ubifs_inode(inode)->ui_size = disk_link.len - 1;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1109

d7f0b70d3   Subodh Nijsure   UBIFS: Add securi...
1110
1111
  	err = ubifs_init_security(dir, inode, &dentry->d_name);
  	if (err)
9401a795c   Taesoo Kim   UBIFS: fix incorr...
1112
  		goto out_inode;
d7f0b70d3   Subodh Nijsure   UBIFS: Add securi...
1113

1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1114
1115
1116
1117
  	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;
ca7f85be8   Richard Weinberger   ubifs: Add suppor...
1118
  	err = ubifs_jnl_update(c, dir, &nm, inode, 0, 0);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1119
1120
1121
  	if (err)
  		goto out_cancel;
  	mutex_unlock(&dir_ui->ui_mutex);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1122
1123
  	insert_inode_hash(inode);
  	d_instantiate(dentry, inode);
6b46d4441   Eric Biggers   ubifs: free the e...
1124
1125
  	err = 0;
  	goto out_fname;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1126
1127
1128
1129
1130
1131
1132
1133
  
  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);
ca7f85be8   Richard Weinberger   ubifs: Add suppor...
1134
1135
  out_fname:
  	fscrypt_free_filename(&nm);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1136
1137
1138
1139
1140
1141
  out_budg:
  	ubifs_release_budget(c, &req);
  	return err;
  }
  
  /**
9e0a1fff8   Richard Weinberger   ubifs: Implement ...
1142
   * lock_4_inodes - a wrapper for locking three UBIFS inodes.
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1143
1144
1145
   * @inode1: first inode
   * @inode2: second inode
   * @inode3: third inode
9e0a1fff8   Richard Weinberger   ubifs: Implement ...
1146
   * @inode4: fouth inode
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1147
   *
82c1593ca   Artem Bityutskiy   UBIFS: simplify l...
1148
   * This function is used for 'ubifs_rename()' and @inode1 may be the same as
9e0a1fff8   Richard Weinberger   ubifs: Implement ...
1149
   * @inode2 whereas @inode3 and @inode4 may be %NULL.
82c1593ca   Artem Bityutskiy   UBIFS: simplify l...
1150
1151
1152
1153
   *
   * 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...
1154
   */
9e0a1fff8   Richard Weinberger   ubifs: Implement ...
1155
1156
  static void lock_4_inodes(struct inode *inode1, struct inode *inode2,
  			  struct inode *inode3, struct inode *inode4)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1157
  {
82c1593ca   Artem Bityutskiy   UBIFS: simplify l...
1158
1159
1160
1161
1162
  	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 ...
1163
1164
  	if (inode4)
  		mutex_lock_nested(&ubifs_inode(inode4)->ui_mutex, WB_MUTEX_4);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1165
1166
1167
  }
  
  /**
9e0a1fff8   Richard Weinberger   ubifs: Implement ...
1168
   * unlock_4_inodes - a wrapper for unlocking three UBIFS inodes for rename.
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1169
1170
1171
   * @inode1: first inode
   * @inode2: second inode
   * @inode3: third inode
9e0a1fff8   Richard Weinberger   ubifs: Implement ...
1172
   * @inode4: fouth inode
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1173
   */
9e0a1fff8   Richard Weinberger   ubifs: Implement ...
1174
1175
  static void unlock_4_inodes(struct inode *inode1, struct inode *inode2,
  			    struct inode *inode3, struct inode *inode4)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1176
  {
9e0a1fff8   Richard Weinberger   ubifs: Implement ...
1177
1178
  	if (inode4)
  		mutex_unlock(&ubifs_inode(inode4)->ui_mutex);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1179
1180
  	if (inode3)
  		mutex_unlock(&ubifs_inode(inode3)->ui_mutex);
82c1593ca   Artem Bityutskiy   UBIFS: simplify l...
1181
1182
1183
  	if (inode1 != inode2)
  		mutex_unlock(&ubifs_inode(inode2)->ui_mutex);
  	mutex_unlock(&ubifs_inode(inode1)->ui_mutex);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1184
  }
390975ac3   Richard Weinberger   ubifs: Rename ubi...
1185
1186
1187
  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...
1188
1189
  {
  	struct ubifs_info *c = old_dir->i_sb->s_fs_info;
2b0143b5c   David Howells   VFS: normal files...
1190
1191
  	struct inode *old_inode = d_inode(old_dentry);
  	struct inode *new_inode = d_inode(new_dentry);
9e0a1fff8   Richard Weinberger   ubifs: Implement ...
1192
  	struct inode *whiteout = NULL;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1193
  	struct ubifs_inode *old_inode_ui = ubifs_inode(old_inode);
9e0a1fff8   Richard Weinberger   ubifs: Implement ...
1194
  	struct ubifs_inode *whiteout_ui = NULL;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1195
1196
  	int err, release, sync = 0, move = (new_dir != old_dir);
  	int is_dir = S_ISDIR(old_inode->i_mode);
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
1197
  	int unlink = !!new_inode, new_sz, old_sz;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1198
1199
1200
  	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...
1201
  			.dirtied_ino_d = ALIGN(old_inode_ui->data_len, 8) };
95582b008   Deepa Dinamani   vfs: change inode...
1202
  	struct timespec64 time;
3f649ab72   Kees Cook   treewide: Remove ...
1203
  	unsigned int saved_nlink;
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
1204
  	struct fscrypt_name old_nm, new_nm;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1205
1206
1207
1208
1209
1210
1211
1212
1213
  
  	/*
  	 * 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 ...
1214
  	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
1215
  		old_dentry, old_inode->i_ino, old_dir->i_ino,
9e0a1fff8   Richard Weinberger   ubifs: Implement ...
1216
  		new_dentry, new_dir->i_ino, flags);
9ca2d7326   Richard Weinberger   ubifs: Limit numb...
1217
  	if (unlink) {
6eb61d587   Richard Weinberger   ubifs: Pass struc...
1218
  		ubifs_assert(c, inode_is_locked(new_inode));
82c1593ca   Artem Bityutskiy   UBIFS: simplify l...
1219

9ca2d7326   Richard Weinberger   ubifs: Limit numb...
1220
1221
1222
1223
  		err = ubifs_purge_xattrs(new_inode);
  		if (err)
  			return err;
  	}
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1224
  	if (unlink && is_dir) {
f6337d842   Richard Weinberger   ubifs: Export ubi...
1225
  		err = ubifs_check_dir_empty(new_inode);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1226
1227
1228
  		if (err)
  			return err;
  	}
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
1229
  	err = fscrypt_setup_filename(old_dir, &old_dentry->d_name, 0, &old_nm);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1230
1231
  	if (err)
  		return err;
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
  
  	err = fscrypt_setup_filename(new_dir, &new_dentry->d_name, 0, &new_nm);
  	if (err) {
  		fscrypt_free_filename(&old_nm);
  		return err;
  	}
  
  	new_sz = CALC_DENT_SIZE(fname_len(&new_nm));
  	old_sz = CALC_DENT_SIZE(fname_len(&old_nm));
  
  	err = ubifs_budget_space(c, &req);
  	if (err) {
  		fscrypt_free_filename(&old_nm);
  		fscrypt_free_filename(&new_nm);
  		return err;
  	}
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1248
1249
  	err = ubifs_budget_space(c, &ino_req);
  	if (err) {
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
1250
1251
  		fscrypt_free_filename(&old_nm);
  		fscrypt_free_filename(&new_nm);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1252
1253
1254
  		ubifs_release_budget(c, &req);
  		return err;
  	}
9e0a1fff8   Richard Weinberger   ubifs: Implement ...
1255
1256
1257
1258
1259
  	if (flags & RENAME_WHITEOUT) {
  		union ubifs_dev_desc *dev = NULL;
  
  		dev = kmalloc(sizeof(union ubifs_dev_desc), GFP_NOFS);
  		if (!dev) {
bb50c6324   Hyunchul Lee   ubifs: Fix memory...
1260
1261
  			err = -ENOMEM;
  			goto out_release;
9e0a1fff8   Richard Weinberger   ubifs: Implement ...
1262
1263
1264
1265
  		}
  
  		err = do_tmpfile(old_dir, old_dentry, S_IFCHR | WHITEOUT_MODE, &whiteout);
  		if (err) {
9e0a1fff8   Richard Weinberger   ubifs: Implement ...
1266
  			kfree(dev);
bb50c6324   Hyunchul Lee   ubifs: Fix memory...
1267
  			goto out_release;
9e0a1fff8   Richard Weinberger   ubifs: Implement ...
1268
1269
1270
1271
1272
1273
  		}
  
  		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));
6eb61d587   Richard Weinberger   ubifs: Pass struc...
1274
  		ubifs_assert(c, !whiteout_ui->dirty);
9e0a1fff8   Richard Weinberger   ubifs: Implement ...
1275
1276
1277
  	}
  
  	lock_4_inodes(old_dir, new_dir, new_inode, whiteout);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1278
1279
1280
1281
1282
  
  	/*
  	 * Like most other Unix systems, set the @i_ctime for inodes on a
  	 * rename.
  	 */
607a11ad9   Deepa Dinamani   fs: ubifs: replac...
1283
  	time = current_time(old_dir);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
  	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...
1324
  		 * directory, just clear @i_nlink.
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1325
  		 */
c43be1085   Artem Bityutskiy   UBIFS: do not use...
1326
  		saved_nlink = new_inode->i_nlink;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1327
  		if (is_dir)
c43be1085   Artem Bityutskiy   UBIFS: do not use...
1328
1329
  			clear_nlink(new_inode);
  		else
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1330
1331
  			drop_nlink(new_inode);
  		new_inode->i_ctime = time;
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
  	} 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 ...
1347
1348
1349
1350
1351
1352
1353
1354
  
  	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) {
9e0a1fff8   Richard Weinberger   ubifs: Implement ...
1355
1356
1357
  			kfree(whiteout_ui->data);
  			whiteout_ui->data_len = 0;
  			iput(whiteout);
bb50c6324   Hyunchul Lee   ubifs: Fix memory...
1358
  			goto out_release;
9e0a1fff8   Richard Weinberger   ubifs: Implement ...
1359
1360
1361
1362
1363
1364
1365
  		}
  
  		inc_nlink(whiteout);
  		mark_inode_dirty(whiteout);
  		whiteout->i_state &= ~I_LINKABLE;
  		iput(whiteout);
  	}
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
1366
1367
  	err = ubifs_jnl_rename(c, old_dir, old_inode, &old_nm, new_dir,
  			       new_inode, &new_nm, whiteout, sync);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1368
1369
  	if (err)
  		goto out_cancel;
9e0a1fff8   Richard Weinberger   ubifs: Implement ...
1370
  	unlock_4_inodes(old_dir, new_dir, new_inode, whiteout);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
  	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...
1381
  		err = old_inode->i_sb->s_op->write_inode(old_inode, NULL);
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
1382
1383
1384
  
  	fscrypt_free_filename(&old_nm);
  	fscrypt_free_filename(&new_nm);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1385
1386
1387
1388
  	return err;
  
  out_cancel:
  	if (unlink) {
c43be1085   Artem Bityutskiy   UBIFS: do not use...
1389
  		set_nlink(new_inode, saved_nlink);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
  	} 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 ...
1406
1407
1408
1409
1410
  	if (whiteout) {
  		drop_nlink(whiteout);
  		iput(whiteout);
  	}
  	unlock_4_inodes(old_dir, new_dir, new_inode, whiteout);
bb50c6324   Hyunchul Lee   ubifs: Fix memory...
1411
  out_release:
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1412
1413
  	ubifs_release_budget(c, &ino_req);
  	ubifs_release_budget(c, &req);
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
1414
1415
  	fscrypt_free_filename(&old_nm);
  	fscrypt_free_filename(&new_nm);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1416
1417
  	return err;
  }
9ec64962a   Richard Weinberger   ubifs: Implement ...
1418
1419
1420
1421
1422
1423
1424
1425
1426
  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);
95582b008   Deepa Dinamani   vfs: change inode...
1427
  	struct timespec64 time;
9ec64962a   Richard Weinberger   ubifs: Implement ...
1428
  	int err;
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
1429
  	struct fscrypt_name fst_nm, snd_nm;
9ec64962a   Richard Weinberger   ubifs: Implement ...
1430

6eb61d587   Richard Weinberger   ubifs: Pass struc...
1431
  	ubifs_assert(c, fst_inode && snd_inode);
9ec64962a   Richard Weinberger   ubifs: Implement ...
1432

f4f61d2cc   Richard Weinberger   ubifs: Implement ...
1433
1434
1435
1436
1437
1438
1439
1440
1441
  	err = fscrypt_setup_filename(old_dir, &old_dentry->d_name, 0, &fst_nm);
  	if (err)
  		return err;
  
  	err = fscrypt_setup_filename(new_dir, &new_dentry->d_name, 0, &snd_nm);
  	if (err) {
  		fscrypt_free_filename(&fst_nm);
  		return err;
  	}
9ec64962a   Richard Weinberger   ubifs: Implement ...
1442
  	lock_4_inodes(old_dir, new_dir, NULL, NULL);
607a11ad9   Deepa Dinamani   fs: ubifs: replac...
1443
  	time = current_time(old_dir);
9ec64962a   Richard Weinberger   ubifs: Implement ...
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
  	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);
  		}
  	}
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
1459
1460
  	err = ubifs_jnl_xrename(c, old_dir, fst_inode, &fst_nm, new_dir,
  				snd_inode, &snd_nm, sync);
9ec64962a   Richard Weinberger   ubifs: Implement ...
1461
1462
1463
  
  	unlock_4_inodes(old_dir, new_dir, NULL, NULL);
  	ubifs_release_budget(c, &req);
f4f61d2cc   Richard Weinberger   ubifs: Implement ...
1464
1465
  	fscrypt_free_filename(&fst_nm);
  	fscrypt_free_filename(&snd_nm);
9ec64962a   Richard Weinberger   ubifs: Implement ...
1466
1467
  	return err;
  }
390975ac3   Richard Weinberger   ubifs: Rename ubi...
1468
  static int ubifs_rename(struct inode *old_dir, struct dentry *old_dentry,
9ec64962a   Richard Weinberger   ubifs: Implement ...
1469
1470
1471
  			struct inode *new_dir, struct dentry *new_dentry,
  			unsigned int flags)
  {
0c1ad5242   Eric Biggers   ubifs: switch to ...
1472
  	int err;
6eb61d587   Richard Weinberger   ubifs: Pass struc...
1473
  	struct ubifs_info *c = old_dir->i_sb->s_fs_info;
0c1ad5242   Eric Biggers   ubifs: switch to ...
1474

9ec64962a   Richard Weinberger   ubifs: Implement ...
1475
1476
  	if (flags & ~(RENAME_NOREPLACE | RENAME_WHITEOUT | RENAME_EXCHANGE))
  		return -EINVAL;
6eb61d587   Richard Weinberger   ubifs: Pass struc...
1477
1478
  	ubifs_assert(c, inode_is_locked(old_dir));
  	ubifs_assert(c, inode_is_locked(new_dir));
9ec64962a   Richard Weinberger   ubifs: Implement ...
1479

0c1ad5242   Eric Biggers   ubifs: switch to ...
1480
1481
1482
1483
  	err = fscrypt_prepare_rename(old_dir, old_dentry, new_dir, new_dentry,
  				     flags);
  	if (err)
  		return err;
9ec64962a   Richard Weinberger   ubifs: Implement ...
1484
1485
  	if (flags & RENAME_EXCHANGE)
  		return ubifs_xrename(old_dir, old_dentry, new_dir, new_dentry);
390975ac3   Richard Weinberger   ubifs: Rename ubi...
1486
  	return do_rename(old_dir, old_dentry, new_dir, new_dentry, flags);
9ec64962a   Richard Weinberger   ubifs: Implement ...
1487
  }
a528d35e8   David Howells   statx: Add a syst...
1488
1489
  int ubifs_getattr(const struct path *path, struct kstat *stat,
  		  u32 request_mask, unsigned int flags)
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1490
1491
  {
  	loff_t size;
a528d35e8   David Howells   statx: Add a syst...
1492
  	struct inode *inode = d_inode(path->dentry);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1493
1494
1495
  	struct ubifs_inode *ui = ubifs_inode(inode);
  
  	mutex_lock(&ui->ui_mutex);
a02a6eba9   Richard Weinberger   ubifs: Wire-up st...
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
  
  	if (ui->flags & UBIFS_APPEND_FL)
  		stat->attributes |= STATX_ATTR_APPEND;
  	if (ui->flags & UBIFS_COMPR_FL)
  		stat->attributes |= STATX_ATTR_COMPRESSED;
  	if (ui->flags & UBIFS_CRYPT_FL)
  		stat->attributes |= STATX_ATTR_ENCRYPTED;
  	if (ui->flags & UBIFS_IMMUTABLE_FL)
  		stat->attributes |= STATX_ATTR_IMMUTABLE;
  
  	stat->attributes_mask |= (STATX_ATTR_APPEND |
  				STATX_ATTR_COMPRESSED |
  				STATX_ATTR_ENCRYPTED |
  				STATX_ATTR_IMMUTABLE);
6d42e7e9f   Al Viro   ubifs: use generi...
1510
  	generic_fillattr(inode, stat);
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
  	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;
  }
ba40e6a3c   Richard Weinberger   ubifs: Implement ...
1540
1541
  static int ubifs_dir_open(struct inode *dir, struct file *file)
  {
50d9fad73   Eric Biggers   ubifs: use IS_ENC...
1542
  	if (IS_ENCRYPTED(dir))
ba40e6a3c   Richard Weinberger   ubifs: Implement ...
1543
1544
1545
1546
  		return fscrypt_get_encryption_info(dir) ? -EACCES : 0;
  
  	return 0;
  }
e8b815663   Artem Bityutskiy   UBIFS: constify o...
1547
  const struct inode_operations ubifs_dir_inode_operations = {
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1548
1549
1550
1551
1552
1553
1554
1555
  	.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...
1556
  	.rename      = ubifs_rename,
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1557
1558
  	.setattr     = ubifs_setattr,
  	.getattr     = ubifs_getattr,
7e5471ce6   Stefan Agner   ubifs: introduce ...
1559
  #ifdef CONFIG_UBIFS_FS_XATTR
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1560
  	.listxattr   = ubifs_listxattr,
7e5471ce6   Stefan Agner   ubifs: introduce ...
1561
  #endif
8c1c5f263   Dongsheng Yang   ubifs: introduce ...
1562
  	.update_time = ubifs_update_time,
474b93704   Richard Weinberger   ubifs: Implement ...
1563
  	.tmpfile     = ubifs_tmpfile,
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1564
  };
e8b815663   Artem Bityutskiy   UBIFS: constify o...
1565
  const struct file_operations ubifs_dir_operations = {
01122e068   Al Viro   [readdir] convert...
1566
  	.llseek         = generic_file_llseek,
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1567
1568
  	.release        = ubifs_dir_release,
  	.read           = generic_read_dir,
c51da20c4   Al Viro   more trivial ->it...
1569
  	.iterate_shared = ubifs_readdir,
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1570
1571
  	.fsync          = ubifs_fsync,
  	.unlocked_ioctl = ubifs_ioctl,
ba40e6a3c   Richard Weinberger   ubifs: Implement ...
1572
  	.open		= ubifs_dir_open,
1e51764a3   Artem Bityutskiy   UBIFS: add new fl...
1573
1574
1575
1576
  #ifdef CONFIG_COMPAT
  	.compat_ioctl   = ubifs_compat_ioctl,
  #endif
  };