Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0
2 : /*
3 : * Copyright (c) 2000-2006 Silicon Graphics, Inc.
4 : * Copyright (c) 2012-2013 Red Hat, Inc.
5 : * All rights reserved.
6 : */
7 : #include "xfs.h"
8 : #include "xfs_shared.h"
9 : #include "xfs_fs.h"
10 : #include "xfs_format.h"
11 : #include "xfs_log_format.h"
12 : #include "xfs_trans_resv.h"
13 : #include "xfs_bit.h"
14 : #include "xfs_mount.h"
15 : #include "xfs_dir2.h"
16 : #include "xfs_inode.h"
17 : #include "xfs_bmap.h"
18 : #include "xfs_bmap_btree.h"
19 : #include "xfs_quota.h"
20 : #include "xfs_symlink.h"
21 : #include "xfs_trans_space.h"
22 : #include "xfs_trace.h"
23 : #include "xfs_trans.h"
24 : #include "xfs_ialloc.h"
25 : #include "xfs_error.h"
26 :
27 : /* ----- Kernel only functions below ----- */
28 : int
29 204241425 : xfs_readlink_bmap_ilocked(
30 : struct xfs_inode *ip,
31 : char *link)
32 : {
33 204241425 : struct xfs_mount *mp = ip->i_mount;
34 204241425 : struct xfs_bmbt_irec mval[XFS_SYMLINK_MAPS];
35 204241425 : struct xfs_buf *bp;
36 204241425 : xfs_daddr_t d;
37 204241425 : char *cur_chunk;
38 204241425 : int pathlen = ip->i_disk_size;
39 204241425 : int nmaps = XFS_SYMLINK_MAPS;
40 204241425 : int byte_cnt;
41 204241425 : int n;
42 204241425 : int error = 0;
43 204241425 : int fsblocks = 0;
44 204241425 : int offset;
45 :
46 204241425 : ASSERT(xfs_isilocked(ip, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
47 :
48 204277711 : fsblocks = xfs_symlink_blocks(mp, pathlen);
49 204273653 : error = xfs_bmapi_read(ip, 0, fsblocks, mval, &nmaps, 0);
50 204337830 : if (error)
51 0 : goto out;
52 :
53 : offset = 0;
54 408674157 : for (n = 0; n < nmaps; n++) {
55 204341462 : d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock);
56 204341460 : byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount);
57 :
58 204275183 : error = xfs_buf_read(mp->m_ddev_targp, d, BTOBB(byte_cnt), 0,
59 : &bp, &xfs_symlink_buf_ops);
60 204308095 : if (error)
61 2 : return error;
62 204308093 : byte_cnt = XFS_SYMLINK_BUF_SPACE(mp, byte_cnt);
63 204308093 : if (pathlen < byte_cnt)
64 : byte_cnt = pathlen;
65 :
66 204308093 : cur_chunk = bp->b_addr;
67 204308093 : if (xfs_has_crc(mp)) {
68 204331584 : if (!xfs_symlink_hdr_ok(ip->i_ino, offset,
69 : byte_cnt, bp)) {
70 0 : error = -EFSCORRUPTED;
71 0 : xfs_alert(mp,
72 : "symlink header does not match required off/len/owner (0x%x/Ox%x,0x%llx)",
73 : offset, byte_cnt, ip->i_ino);
74 0 : xfs_buf_relse(bp);
75 0 : goto out;
76 :
77 : }
78 :
79 204244637 : cur_chunk += sizeof(struct xfs_dsymlink_hdr);
80 : }
81 :
82 408442292 : memcpy(link + offset, cur_chunk, byte_cnt);
83 :
84 204221146 : pathlen -= byte_cnt;
85 204221146 : offset += byte_cnt;
86 :
87 204221146 : xfs_buf_relse(bp);
88 : }
89 204332695 : ASSERT(pathlen == 0);
90 :
91 204332695 : link[ip->i_disk_size] = '\0';
92 204332695 : error = 0;
93 :
94 : out:
95 : return error;
96 : }
97 :
98 : int
99 265910751 : xfs_readlink(
100 : struct xfs_inode *ip,
101 : char *link)
102 : {
103 265910751 : struct xfs_mount *mp = ip->i_mount;
104 265910751 : xfs_fsize_t pathlen;
105 265910751 : int error = -EFSCORRUPTED;
106 :
107 265910751 : trace_xfs_readlink(ip);
108 :
109 531854706 : if (xfs_is_shutdown(mp))
110 : return -EIO;
111 :
112 265927317 : xfs_ilock(ip, XFS_ILOCK_SHARED);
113 :
114 266050157 : pathlen = ip->i_disk_size;
115 266050157 : if (!pathlen)
116 0 : goto out;
117 :
118 266050157 : if (pathlen < 0 || pathlen > XFS_SYMLINK_MAXLEN) {
119 0 : xfs_alert(mp, "%s: inode (%llu) bad symlink length (%lld)",
120 : __func__, (unsigned long long) ip->i_ino,
121 : (long long) pathlen);
122 0 : ASSERT(0);
123 0 : goto out;
124 : }
125 :
126 266050157 : if (ip->i_df.if_format == XFS_DINODE_FMT_LOCAL) {
127 : /*
128 : * The VFS crashes on a NULL pointer, so return -EFSCORRUPTED
129 : * if if_data is junk.
130 : */
131 87454392 : if (XFS_IS_CORRUPT(ip->i_mount, !ip->i_df.if_u1.if_data))
132 0 : goto out;
133 :
134 174908784 : memcpy(link, ip->i_df.if_u1.if_data, pathlen + 1);
135 87454392 : error = 0;
136 : } else {
137 178595765 : error = xfs_readlink_bmap_ilocked(ip, link);
138 : }
139 :
140 266104684 : out:
141 266104684 : xfs_iunlock(ip, XFS_ILOCK_SHARED);
142 266104684 : return error;
143 : }
144 :
145 : int
146 238010029 : xfs_symlink(
147 : struct mnt_idmap *idmap,
148 : struct xfs_inode *dp,
149 : struct xfs_name *link_name,
150 : const char *target_path,
151 : umode_t mode,
152 : struct xfs_inode **ipp)
153 : {
154 238010029 : struct xfs_mount *mp = dp->i_mount;
155 238010029 : struct xfs_trans *tp = NULL;
156 238010029 : struct xfs_inode *ip = NULL;
157 238010029 : int error = 0;
158 238010029 : int pathlen;
159 238010029 : bool unlock_dp_on_error = false;
160 238010029 : xfs_fileoff_t first_fsb;
161 238010029 : xfs_filblks_t fs_blocks;
162 238010029 : int nmaps;
163 238010029 : struct xfs_bmbt_irec mval[XFS_SYMLINK_MAPS];
164 238010029 : xfs_daddr_t d;
165 238010029 : const char *cur_chunk;
166 238010029 : int byte_cnt;
167 238010029 : int n;
168 238010029 : struct xfs_buf *bp;
169 238010029 : prid_t prid;
170 238010029 : struct xfs_dquot *udqp = NULL;
171 238010029 : struct xfs_dquot *gdqp = NULL;
172 238010029 : struct xfs_dquot *pdqp = NULL;
173 238010029 : uint resblks;
174 238010029 : xfs_ino_t ino;
175 :
176 238010029 : *ipp = NULL;
177 :
178 238010029 : trace_xfs_symlink(dp, link_name);
179 :
180 476056792 : if (xfs_is_shutdown(mp))
181 : return -EIO;
182 :
183 : /*
184 : * Check component lengths of the target path name.
185 : */
186 238028396 : pathlen = strlen(target_path);
187 238028396 : if (pathlen >= XFS_SYMLINK_MAXLEN) /* total string too long */
188 : return -ENAMETOOLONG;
189 27320086 : ASSERT(pathlen > 0);
190 :
191 27320086 : prid = xfs_get_initial_prid(dp);
192 :
193 : /*
194 : * Make sure that we have allocated dquot(s) on disk.
195 : */
196 27320086 : error = xfs_qm_vop_dqalloc(dp, mapped_fsuid(idmap, &init_user_ns),
197 : mapped_fsgid(idmap, &init_user_ns), prid,
198 : XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT,
199 : &udqp, &gdqp, &pdqp);
200 27296043 : if (error)
201 : return error;
202 :
203 : /*
204 : * The symlink will fit into the inode data fork?
205 : * There can't be any attributes so we get the whole variable part.
206 : */
207 27296032 : if (pathlen <= XFS_LITINO(mp))
208 : fs_blocks = 0;
209 : else
210 18328253 : fs_blocks = xfs_symlink_blocks(mp, pathlen);
211 27296007 : resblks = XFS_SYMLINK_SPACE_RES(mp, link_name->len, fs_blocks);
212 :
213 27296007 : error = xfs_trans_alloc_icreate(mp, &M_RES(mp)->tr_symlink, udqp, gdqp,
214 : pdqp, resblks, &tp);
215 27296502 : if (error)
216 16510 : goto out_release_dquots;
217 :
218 27279992 : xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
219 27279740 : unlock_dp_on_error = true;
220 :
221 : /*
222 : * Check whether the directory allows new symlinks or not.
223 : */
224 27279740 : if (dp->i_diflags & XFS_DIFLAG_NOSYMLINKS) {
225 2 : error = -EPERM;
226 2 : goto out_trans_cancel;
227 : }
228 :
229 : /*
230 : * Allocate an inode for the symlink.
231 : */
232 27279738 : error = xfs_dialloc(&tp, dp->i_ino, S_IFLNK, &ino);
233 27279796 : if (!error)
234 27279875 : error = xfs_init_new_inode(idmap, tp, dp, ino,
235 27279875 : S_IFLNK | (mode & ~S_IFMT), 1, 0, prid,
236 : false, &ip);
237 27279748 : if (error)
238 7 : goto out_trans_cancel;
239 :
240 : /*
241 : * Now we join the directory inode to the transaction. We do not do it
242 : * earlier because xfs_dir_ialloc might commit the previous transaction
243 : * (and release all the locks). An error from here on will result in
244 : * the transaction cancel unlocking dp so don't do it explicitly in the
245 : * error path.
246 : */
247 27279741 : xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);
248 27279680 : unlock_dp_on_error = false;
249 :
250 : /*
251 : * Also attach the dquot(s) to it, if applicable.
252 : */
253 27279680 : xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp, pdqp);
254 :
255 27279758 : resblks -= XFS_IALLOC_SPACE_RES(mp);
256 : /*
257 : * If the symlink will fit into the inode, write it inline.
258 : */
259 27279758 : if (pathlen <= xfs_inode_data_fork_size(ip)) {
260 8962648 : xfs_init_local_fork(ip, XFS_DATA_FORK, target_path, pathlen);
261 :
262 8962792 : ip->i_disk_size = pathlen;
263 8962792 : ip->i_df.if_format = XFS_DINODE_FMT_LOCAL;
264 8962792 : xfs_trans_log_inode(tp, ip, XFS_ILOG_DDATA | XFS_ILOG_CORE);
265 : } else {
266 18317110 : int offset;
267 :
268 18317110 : first_fsb = 0;
269 18317110 : nmaps = XFS_SYMLINK_MAPS;
270 :
271 18317110 : error = xfs_bmapi_write(tp, ip, first_fsb, fs_blocks,
272 : XFS_BMAPI_METADATA, resblks, mval, &nmaps);
273 18315882 : if (error)
274 3 : goto out_trans_cancel;
275 :
276 18315879 : resblks -= fs_blocks;
277 18315879 : ip->i_disk_size = pathlen;
278 18315879 : xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
279 :
280 18315879 : cur_chunk = target_path;
281 18315879 : offset = 0;
282 54948529 : for (n = 0; n < nmaps; n++) {
283 18315896 : char *buf;
284 :
285 18315896 : d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock);
286 18316470 : byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount);
287 18316487 : error = xfs_trans_get_buf(tp, mp->m_ddev_targp, d,
288 18316487 : BTOBB(byte_cnt), 0, &bp);
289 18316712 : if (error)
290 0 : goto out_trans_cancel;
291 18316712 : bp->b_ops = &xfs_symlink_buf_ops;
292 :
293 18316712 : byte_cnt = XFS_SYMLINK_BUF_SPACE(mp, byte_cnt);
294 18316712 : byte_cnt = min(byte_cnt, pathlen);
295 :
296 18316712 : buf = bp->b_addr;
297 18316712 : buf += xfs_symlink_hdr_set(mp, ip->i_ino, offset,
298 : byte_cnt, bp);
299 :
300 36633080 : memcpy(buf, cur_chunk, byte_cnt);
301 :
302 18316540 : cur_chunk += byte_cnt;
303 18316540 : pathlen -= byte_cnt;
304 18316540 : offset += byte_cnt;
305 :
306 18316540 : xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SYMLINK_BUF);
307 18316220 : xfs_trans_log_buf(tp, bp, 0, (buf + byte_cnt - 1) -
308 18316220 : (char *)bp->b_addr);
309 : }
310 18316754 : ASSERT(pathlen == 0);
311 : }
312 27279611 : i_size_write(VFS_I(ip), ip->i_disk_size);
313 :
314 : /*
315 : * Create the directory entry for the symlink.
316 : */
317 27279611 : error = xfs_dir_createname(tp, dp, link_name, ip->i_ino, resblks);
318 27278318 : if (error)
319 2 : goto out_trans_cancel;
320 27278316 : xfs_trans_ichgtime(tp, dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
321 27278422 : xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
322 :
323 : /*
324 : * If this is a synchronous mount, make sure that the
325 : * symlink transaction goes to disk before returning to
326 : * the user.
327 : */
328 27279738 : if (xfs_has_wsync(mp) || xfs_has_dirsync(mp))
329 0 : xfs_trans_set_sync(tp);
330 :
331 27279738 : error = xfs_trans_commit(tp);
332 27279906 : if (error)
333 17 : goto out_release_inode;
334 :
335 27279889 : xfs_qm_dqrele(udqp);
336 27280103 : xfs_qm_dqrele(gdqp);
337 27280138 : xfs_qm_dqrele(pdqp);
338 :
339 27280152 : *ipp = ip;
340 27280152 : return 0;
341 :
342 14 : out_trans_cancel:
343 14 : xfs_trans_cancel(tp);
344 31 : out_release_inode:
345 : /*
346 : * Wait until after the current transaction is aborted to finish the
347 : * setup of the inode and release the inode. This prevents recursive
348 : * transactions and deadlocks from xfs_inactive.
349 : */
350 31 : if (ip) {
351 22 : xfs_finish_inode_setup(ip);
352 22 : xfs_irele(ip);
353 : }
354 9 : out_release_dquots:
355 16541 : xfs_qm_dqrele(udqp);
356 16540 : xfs_qm_dqrele(gdqp);
357 16541 : xfs_qm_dqrele(pdqp);
358 :
359 16541 : if (unlock_dp_on_error)
360 9 : xfs_iunlock(dp, XFS_ILOCK_EXCL);
361 : return error;
362 : }
363 :
364 : /*
365 : * Free a symlink that has blocks associated with it.
366 : *
367 : * Note: zero length symlinks are not allowed to exist. When we set the size to
368 : * zero, also change it to a regular file so that it does not get written to
369 : * disk as a zero length symlink. The inode is on the unlinked list already, so
370 : * userspace cannot find this inode anymore, so this change is not user visible
371 : * but allows us to catch corrupt zero-length symlinks in the verifiers.
372 : */
373 : STATIC int
374 17909836 : xfs_inactive_symlink_rmt(
375 : struct xfs_inode *ip)
376 : {
377 17909836 : struct xfs_buf *bp;
378 17909836 : int done;
379 17909836 : int error;
380 17909836 : int i;
381 17909836 : xfs_mount_t *mp;
382 17909836 : xfs_bmbt_irec_t mval[XFS_SYMLINK_MAPS];
383 17909836 : int nmaps;
384 17909836 : int size;
385 17909836 : xfs_trans_t *tp;
386 :
387 17909836 : mp = ip->i_mount;
388 17909836 : ASSERT(!xfs_need_iread_extents(&ip->i_df));
389 : /*
390 : * We're freeing a symlink that has some
391 : * blocks allocated to it. Free the
392 : * blocks here. We know that we've got
393 : * either 1 or 2 extents and that we can
394 : * free them all in one bunmapi call.
395 : */
396 17910227 : ASSERT(ip->i_df.if_nextents > 0 && ip->i_df.if_nextents <= 2);
397 :
398 17910227 : error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp);
399 17910559 : if (error)
400 : return error;
401 :
402 17910573 : xfs_ilock(ip, XFS_ILOCK_EXCL);
403 17910599 : xfs_trans_ijoin(tp, ip, 0);
404 :
405 : /*
406 : * Lock the inode, fix the size, turn it into a regular file and join it
407 : * to the transaction. Hold it so in the normal path, we still have it
408 : * locked for the second transaction. In the error paths we need it
409 : * held so the cancel won't rele it, see below.
410 : */
411 17909626 : size = (int)ip->i_disk_size;
412 17909626 : ip->i_disk_size = 0;
413 17909626 : VFS_I(ip)->i_mode = (VFS_I(ip)->i_mode & ~S_IFMT) | S_IFREG;
414 17909626 : xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
415 : /*
416 : * Find the block(s) so we can inval and unmap them.
417 : */
418 17910453 : done = 0;
419 17910453 : nmaps = ARRAY_SIZE(mval);
420 17910453 : error = xfs_bmapi_read(ip, 0, xfs_symlink_blocks(mp, size),
421 : mval, &nmaps, 0);
422 17910149 : if (error)
423 0 : goto error_trans_cancel;
424 : /*
425 : * Invalidate the block(s). No validation is done.
426 : */
427 35820431 : for (i = 0; i < nmaps; i++) {
428 71640993 : error = xfs_trans_get_buf(tp, mp->m_ddev_targp,
429 17910132 : XFS_FSB_TO_DADDR(mp, mval[i].br_startblock),
430 17910273 : XFS_FSB_TO_BB(mp, mval[i].br_blockcount), 0,
431 : &bp);
432 17908981 : if (error)
433 0 : goto error_trans_cancel;
434 17908981 : xfs_trans_binval(tp, bp);
435 : }
436 : /*
437 : * Unmap the dead block(s) to the dfops.
438 : */
439 17910299 : error = xfs_bunmapi(tp, ip, 0, size, 0, nmaps, &done);
440 17910156 : if (error)
441 0 : goto error_trans_cancel;
442 17910156 : ASSERT(done);
443 :
444 : /*
445 : * Commit the transaction. This first logs the EFI and the inode, then
446 : * rolls and commits the transaction that frees the extents.
447 : */
448 17910156 : xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
449 17910177 : error = xfs_trans_commit(tp);
450 17910611 : if (error) {
451 4 : ASSERT(xfs_is_shutdown(mp));
452 2 : goto error_unlock;
453 : }
454 :
455 : /*
456 : * Remove the memory for extent descriptions (just bookkeeping).
457 : */
458 17910609 : if (ip->i_df.if_bytes)
459 0 : xfs_idata_realloc(ip, -ip->i_df.if_bytes, XFS_DATA_FORK);
460 17910609 : ASSERT(ip->i_df.if_bytes == 0);
461 :
462 17910609 : xfs_iunlock(ip, XFS_ILOCK_EXCL);
463 17910609 : return 0;
464 :
465 0 : error_trans_cancel:
466 0 : xfs_trans_cancel(tp);
467 2 : error_unlock:
468 2 : xfs_iunlock(ip, XFS_ILOCK_EXCL);
469 2 : return error;
470 : }
471 :
472 : /*
473 : * xfs_inactive_symlink - free a symlink
474 : */
475 : int
476 26671020 : xfs_inactive_symlink(
477 : struct xfs_inode *ip)
478 : {
479 26671020 : struct xfs_mount *mp = ip->i_mount;
480 26671020 : int pathlen;
481 :
482 26671020 : trace_xfs_inactive_symlink(ip);
483 :
484 53341960 : if (xfs_is_shutdown(mp))
485 : return -EIO;
486 :
487 26670973 : xfs_ilock(ip, XFS_ILOCK_EXCL);
488 26672525 : pathlen = (int)ip->i_disk_size;
489 26672525 : ASSERT(pathlen);
490 :
491 26672525 : if (pathlen <= 0 || pathlen > XFS_SYMLINK_MAXLEN) {
492 0 : xfs_alert(mp, "%s: inode (0x%llx) bad symlink length (%d)",
493 : __func__, (unsigned long long)ip->i_ino, pathlen);
494 0 : xfs_iunlock(ip, XFS_ILOCK_EXCL);
495 0 : ASSERT(0);
496 0 : return -EFSCORRUPTED;
497 : }
498 :
499 : /*
500 : * Inline fork state gets removed by xfs_difree() so we have nothing to
501 : * do here in that case.
502 : */
503 26672525 : if (ip->i_df.if_format == XFS_DINODE_FMT_LOCAL) {
504 8762591 : xfs_iunlock(ip, XFS_ILOCK_EXCL);
505 8762591 : return 0;
506 : }
507 :
508 17909934 : xfs_iunlock(ip, XFS_ILOCK_EXCL);
509 :
510 : /* remove the remote symlink */
511 17909583 : return xfs_inactive_symlink_rmt(ip);
512 : }
|