Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0-only
2 : /* * This file is part of UBIFS.
3 : *
4 : * Copyright (C) 2006-2008 Nokia Corporation.
5 : * Copyright (C) 2006, 2007 University of Szeged, Hungary
6 : *
7 : * Authors: Artem Bityutskiy (Битюцкий Артём)
8 : * Adrian Hunter
9 : * Zoltan Sogor
10 : */
11 :
12 : /*
13 : * This file implements directory operations.
14 : *
15 : * All FS operations in this file allocate budget before writing anything to the
16 : * media. If they fail to allocate it, the error is returned. The only
17 : * exceptions are 'ubifs_unlink()' and 'ubifs_rmdir()' which keep working even
18 : * if they unable to allocate the budget, because deletion %-ENOSPC failure is
19 : * not what users are usually ready to get. UBIFS budgeting subsystem has some
20 : * space reserved for these purposes.
21 : *
22 : * All operations in this file write all inodes which they change straight
23 : * away, instead of marking them dirty. For example, 'ubifs_link()' changes
24 : * @i_size of the parent inode and writes the parent inode together with the
25 : * target inode. This was done to simplify file-system recovery which would
26 : * otherwise be very difficult to do. The only exception is rename which marks
27 : * the re-named inode dirty (because its @i_ctime is updated) but does not
28 : * write it, but just marks it as dirty.
29 : */
30 :
31 : #include <sys/stat.h>
32 :
33 : #include "linux_err.h"
34 : #include "bitops.h"
35 : #include "kmem.h"
36 : #include "ubifs.h"
37 : #include "defs.h"
38 : #include "debug.h"
39 : #include "key.h"
40 : #include "misc.h"
41 :
42 : /**
43 : * inherit_flags - inherit flags of the parent inode.
44 : * @c: UBIFS file-system description object
45 : * @dir: parent inode
46 : * @mode: new inode mode flags
47 : *
48 : * This is a helper function for 'ubifs_new_inode()' which inherits flag of the
49 : * parent directory inode @dir. UBIFS inodes inherit the following flags:
50 : * o %UBIFS_COMPR_FL, which is useful to switch compression on/of on
51 : * sub-directory basis;
52 : * o %UBIFS_SYNC_FL - useful for the same reasons;
53 : * o %UBIFS_DIRSYNC_FL - similar, but relevant only to directories.
54 : *
55 : * This function returns the inherited flags.
56 : */
57 30 : static int inherit_flags(struct ubifs_info *c, const struct inode *dir,
58 : unsigned int mode)
59 : {
60 : int flags;
61 30 : const struct ubifs_inode *ui = ubifs_inode(dir);
62 :
63 30 : ubifs_assert(c, S_ISDIR(dir->mode));
64 :
65 30 : flags = ui->flags & (UBIFS_COMPR_FL | UBIFS_SYNC_FL | UBIFS_DIRSYNC_FL);
66 30 : if (!S_ISDIR(mode))
67 : /* The "DIRSYNC" flag only applies to directories */
68 0 : flags &= ~UBIFS_DIRSYNC_FL;
69 30 : return flags;
70 : }
71 :
72 : /**
73 : * ubifs_new_inode - allocate new UBIFS inode object.
74 : * @c: UBIFS file-system description object
75 : * @dir: parent inode
76 : * @mode: inode mode flags
77 : *
78 : * This function finds an unused inode number, allocates new ubifs inode and
79 : * initializes it. Returns new ubifs inode in case of success and an error code
80 : * in case of failure.
81 : */
82 35 : static struct ubifs_inode *ubifs_new_inode(struct ubifs_info *c,
83 : const struct inode *dir,
84 : unsigned int mode)
85 : {
86 : int err;
87 35 : time_t now = time(NULL);
88 : struct ubifs_inode *ui;
89 : struct inode *inode;
90 :
91 35 : ui = kzalloc(sizeof(struct ubifs_inode), GFP_KERNEL);
92 35 : if (!ui)
93 : return ERR_PTR(-ENOMEM);
94 :
95 35 : inode = &ui->vfs_inode;
96 35 : inode->atime_sec = inode->ctime_sec = inode->mtime_sec = now;
97 35 : inode->nlink = 1;
98 35 : inode->mode = mode;
99 35 : if (dir) {
100 : /* Create non root dir. */
101 30 : inode->uid = dir->uid;
102 30 : inode->gid = dir->gid;
103 30 : if ((dir->mode & S_ISGID) && S_ISDIR(mode))
104 0 : inode->mode |= S_ISGID;
105 30 : ui->flags = inherit_flags(c, dir, mode);
106 : }
107 35 : if (S_ISDIR(mode))
108 35 : ui->ui_size = UBIFS_INO_NODE_SZ;
109 35 : if (S_ISREG(mode))
110 0 : ui->compr_type = c->default_compr;
111 : else
112 35 : ui->compr_type = UBIFS_COMPR_NONE;
113 :
114 35 : if (dir) {
115 30 : spin_lock(&c->cnt_lock);
116 : /* Inode number overflow is currently not supported */
117 30 : if (c->highest_inum >= INUM_WARN_WATERMARK) {
118 0 : if (c->highest_inum >= INUM_WATERMARK) {
119 0 : spin_unlock(&c->cnt_lock);
120 0 : ubifs_err(c, "out of inode numbers");
121 0 : err = -EINVAL;
122 : goto out;
123 : }
124 0 : ubifs_warn(c, "running out of inode numbers (current %lu, max %u)",
125 : (unsigned long)c->highest_inum, INUM_WATERMARK);
126 : }
127 30 : inode->inum = ++c->highest_inum;
128 : } else {
129 : /* Create root dir. */
130 5 : inode->inum = UBIFS_ROOT_INO;
131 : }
132 : /*
133 : * The creation sequence number remains with this inode for its
134 : * lifetime. All nodes for this inode have a greater sequence number,
135 : * and so it is possible to distinguish obsolete nodes belonging to a
136 : * previous incarnation of the same inode number - for example, for the
137 : * purpose of rebuilding the index.
138 : */
139 35 : ui->creat_sqnum = ++c->max_sqnum;
140 35 : spin_unlock(&c->cnt_lock);
141 :
142 35 : return ui;
143 :
144 0 : out:
145 0 : kfree(ui);
146 0 : return ERR_PTR(err);
147 : }
148 :
149 : /**
150 : * ubifs_lookup_by_inum - look up the UBIFS inode according to inode number.
151 : * @c: UBIFS file-system description object
152 : * @inum: inode number
153 : *
154 : * This function looks up the UBIFS inode according to a given inode number.
155 : * Returns zero in case of success and an error code in case of failure.
156 : */
157 1977 : struct ubifs_inode *ubifs_lookup_by_inum(struct ubifs_info *c, ino_t inum)
158 : {
159 : int err;
160 : union ubifs_key key;
161 : struct inode *inode;
162 : struct ubifs_inode *ui;
163 1977 : struct ubifs_ino_node *ino = NULL;
164 :
165 1977 : ino = kmalloc(UBIFS_MAX_INO_NODE_SZ, GFP_NOFS);
166 1977 : if (!ino)
167 : return ERR_PTR(-ENOMEM);
168 :
169 1977 : ui = kzalloc(sizeof(struct ubifs_inode), GFP_KERNEL);
170 1977 : if (!ui) {
171 : err = -ENOMEM;
172 : goto out;
173 : }
174 :
175 1977 : inode = &ui->vfs_inode;
176 3954 : ino_key_init(c, &key, inum);
177 1977 : err = ubifs_tnc_lookup(c, &key, ino);
178 1977 : if (err) {
179 5 : kfree(ui);
180 5 : ubifs_assert(c, !get_failure_reason_callback(c));
181 : goto out;
182 : }
183 :
184 1972 : inode = &ui->vfs_inode;
185 1972 : inode->inum = inum;
186 1972 : inode->uid = le32_to_cpu(ino->uid);
187 1972 : inode->gid = le32_to_cpu(ino->gid);
188 1972 : inode->mode = le32_to_cpu(ino->mode);
189 1972 : inode->nlink = le32_to_cpu(ino->nlink);
190 1972 : inode->atime_sec = le64_to_cpu(ino->atime_sec);
191 1972 : inode->ctime_sec = le64_to_cpu(ino->ctime_sec);
192 1972 : inode->mtime_sec = le64_to_cpu(ino->mtime_sec);
193 1972 : inode->atime_nsec = le32_to_cpu(ino->atime_nsec);
194 1972 : inode->ctime_nsec = le32_to_cpu(ino->ctime_nsec);
195 1972 : inode->mtime_nsec = le32_to_cpu(ino->mtime_nsec);
196 1972 : ui->creat_sqnum = le64_to_cpu(ino->creat_sqnum);
197 1972 : ui->xattr_size = le32_to_cpu(ino->xattr_size);
198 1972 : ui->xattr_cnt = le32_to_cpu(ino->xattr_cnt);
199 1972 : ui->xattr_names = le32_to_cpu(ino->xattr_names);
200 1972 : ui->compr_type = le16_to_cpu(ino->compr_type);
201 1972 : ui->ui_size = le64_to_cpu(ino->size);
202 1972 : ui->flags = le32_to_cpu(ino->flags);
203 1972 : ui->data_len = le32_to_cpu(ino->data_len);
204 :
205 1977 : out:
206 1977 : kfree(ino);
207 1982 : return err ? ERR_PTR(err) : ui;
208 : }
209 :
210 271 : struct ubifs_inode *ubifs_lookup(struct ubifs_info *c,
211 : struct ubifs_inode *dir_ui,
212 : const struct fscrypt_name *nm)
213 : {
214 : int err;
215 : ino_t inum;
216 : union ubifs_key key;
217 : struct ubifs_dent_node *dent;
218 :
219 271 : if (fname_len(nm) > UBIFS_MAX_NLEN)
220 : return ERR_PTR(-ENAMETOOLONG);
221 :
222 271 : dent = kmalloc(UBIFS_MAX_DENT_NODE_SZ, GFP_NOFS);
223 271 : if (!dent)
224 : return ERR_PTR(-ENOMEM);
225 :
226 271 : dent_key_init(c, &key, dir_ui->vfs_inode.inum, nm);
227 271 : err = ubifs_tnc_lookup_nm(c, &key, dent, nm);
228 271 : if (err) {
229 232 : kfree(dent);
230 232 : ubifs_assert(c, !get_failure_reason_callback(c));
231 464 : return ERR_PTR(err);
232 : }
233 39 : inum = le64_to_cpu(dent->inum);
234 39 : kfree(dent);
235 :
236 39 : return ubifs_lookup_by_inum(c, inum);
237 : }
238 :
239 30 : int ubifs_mkdir(struct ubifs_info *c, struct ubifs_inode *dir_ui,
240 : const struct fscrypt_name *nm, unsigned int mode)
241 : {
242 : struct ubifs_inode *ui;
243 30 : struct inode *inode, *dir = &dir_ui->vfs_inode;
244 : int err, sz_change;
245 30 : struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1,
246 : .dirtied_ino = 1};
247 : /*
248 : * Budget request settings: new inode, new direntry and changing parent
249 : * directory inode.
250 : */
251 30 : dbg_gen("dent '%s', mode %#hx in dir ino %lu",
252 : fname_name(nm), mode, dir->inum);
253 :
254 : /* New dir is not allowed to be created under an encrypted directory. */
255 30 : ubifs_assert(c, !(dir_ui->flags & UBIFS_CRYPT_FL));
256 :
257 30 : err = ubifs_budget_space(c, &req);
258 30 : if (err)
259 : return err;
260 :
261 30 : sz_change = CALC_DENT_SIZE(fname_len(nm));
262 :
263 30 : ui = ubifs_new_inode(c, dir, S_IFDIR | mode);
264 30 : if (IS_ERR(ui)) {
265 0 : err = PTR_ERR(ui);
266 0 : goto out_budg;
267 : }
268 :
269 30 : inode = &ui->vfs_inode;
270 30 : inode->nlink++;
271 30 : dir->nlink++;
272 30 : dir_ui->ui_size += sz_change;
273 30 : dir->ctime_sec = dir->mtime_sec = inode->ctime_sec;
274 30 : err = ubifs_jnl_update_file(c, dir_ui, nm, ui);
275 30 : if (err) {
276 0 : ubifs_err(c, "cannot create directory, error %d", err);
277 : goto out_cancel;
278 : }
279 :
280 30 : kfree(ui);
281 30 : ubifs_release_budget(c, &req);
282 30 : return 0;
283 :
284 0 : out_cancel:
285 0 : dir_ui->ui_size -= sz_change;
286 0 : dir->nlink--;
287 : kfree(ui);
288 0 : out_budg:
289 0 : ubifs_release_budget(c, &req);
290 0 : return err;
291 : }
292 :
293 : /**
294 : * ubifs_link_recovery - link a disconnected file into the target directory.
295 : * @c: UBIFS file-system description object
296 : * @dir_ui: target directory
297 : * @ui: the UBIFS inode of disconnected file
298 : * @nm: directory entry name
299 : *
300 : * This function links the inode of disconnected file to a directory entry name
301 : * under the target directory. Returns zero in case of success and an error code
302 : * in case of failure.
303 : */
304 202 : int ubifs_link_recovery(struct ubifs_info *c, struct ubifs_inode *dir_ui,
305 : struct ubifs_inode *ui, const struct fscrypt_name *nm)
306 : {
307 202 : struct inode *inode = &ui->vfs_inode, *dir = &dir_ui->vfs_inode;
308 : int err, sz_change;
309 404 : struct ubifs_budget_req req = { .new_dent = 1, .dirtied_ino = 2,
310 202 : .dirtied_ino_d = ALIGN(ui->data_len, 8) };
311 202 : time_t now = time(NULL);
312 :
313 : /*
314 : * Budget request settings: new direntry, changing the target inode,
315 : * changing the parent inode.
316 : */
317 202 : dbg_gen("dent '%s' to ino %lu (nlink %d) in dir ino %lu",
318 : fname_name(nm), inode->inum, inode->nlink, dir->inum);
319 :
320 : /* New dir is not allowed to be created under an encrypted directory. */
321 202 : ubifs_assert(c, !(dir_ui->flags & UBIFS_CRYPT_FL));
322 :
323 202 : sz_change = CALC_DENT_SIZE(fname_len(nm));
324 :
325 202 : err = ubifs_budget_space(c, &req);
326 202 : if (err)
327 : return err;
328 :
329 202 : inode->ctime_sec = now;
330 202 : dir_ui->ui_size += sz_change;
331 202 : dir->ctime_sec = dir->mtime_sec = now;
332 202 : err = ubifs_jnl_update_file(c, dir_ui, nm, ui);
333 202 : if (err)
334 : goto out_cancel;
335 :
336 202 : ubifs_release_budget(c, &req);
337 202 : return 0;
338 :
339 0 : out_cancel:
340 0 : dir_ui->ui_size -= sz_change;
341 0 : ubifs_release_budget(c, &req);
342 0 : return err;
343 : }
344 :
345 : /**
346 : * ubifs_create_root - create the root inode.
347 : * @c: UBIFS file-system description object
348 : *
349 : * This function creates a new inode for the root directory. Returns zero in
350 : * case of success and an error code in case of failure.
351 : */
352 5 : int ubifs_create_root(struct ubifs_info *c)
353 : {
354 : int err;
355 : struct inode *inode;
356 5 : struct ubifs_budget_req req = { .new_ino = 1 };
357 : struct ubifs_inode *ui;
358 :
359 : /* Budget request settings: new inode. */
360 5 : dbg_gen("create root dir");
361 :
362 5 : err = ubifs_budget_space(c, &req);
363 5 : if (err)
364 : return err;
365 :
366 5 : ui = ubifs_new_inode(c, NULL, S_IFDIR | S_IRUGO | S_IWUSR | S_IXUGO);
367 5 : if (IS_ERR(ui)) {
368 0 : err = PTR_ERR(ui);
369 0 : goto out_budg;
370 : }
371 :
372 5 : inode = &ui->vfs_inode;
373 5 : inode->nlink = 2;
374 5 : ui->ui_size = UBIFS_INO_NODE_SZ;
375 5 : ui->flags = UBIFS_COMPR_FL;
376 5 : err = ubifs_jnl_update_file(c, NULL, NULL, ui);
377 5 : if (err)
378 : goto out_ui;
379 :
380 5 : kfree(ui);
381 5 : ubifs_release_budget(c, &req);
382 5 : return 0;
383 :
384 0 : out_ui:
385 : kfree(ui);
386 0 : out_budg:
387 0 : ubifs_release_budget(c, &req);
388 0 : ubifs_err(c, "cannot create root dir, error %d", err);
389 : return err;
390 : }
|