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 191397703 : xfs_readlink_bmap_ilocked(
30 : struct xfs_inode *ip,
31 : char *link)
32 : {
33 191397703 : struct xfs_mount *mp = ip->i_mount;
34 191397703 : struct xfs_bmbt_irec mval[XFS_SYMLINK_MAPS];
35 191397703 : struct xfs_buf *bp;
36 191397703 : xfs_daddr_t d;
37 191397703 : char *cur_chunk;
38 191397703 : int pathlen = ip->i_disk_size;
39 191397703 : int nmaps = XFS_SYMLINK_MAPS;
40 191397703 : int byte_cnt;
41 191397703 : int n;
42 191397703 : int error = 0;
43 191397703 : int fsblocks = 0;
44 191397703 : int offset;
45 :
46 191397703 : ASSERT(xfs_isilocked(ip, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
47 :
48 191235751 : fsblocks = xfs_symlink_blocks(mp, pathlen);
49 191254496 : error = xfs_bmapi_read(ip, 0, fsblocks, mval, &nmaps, 0);
50 191337013 : if (error)
51 0 : goto out;
52 :
53 : offset = 0;
54 382876073 : for (n = 0; n < nmaps; n++) {
55 191337816 : d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock);
56 191152146 : byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount);
57 :
58 191293005 : error = xfs_buf_read(mp->m_ddev_targp, d, BTOBB(byte_cnt), 0,
59 : &bp, &xfs_symlink_buf_ops);
60 191298577 : if (error)
61 10 : return error;
62 191298567 : byte_cnt = XFS_SYMLINK_BUF_SPACE(mp, byte_cnt);
63 191298567 : if (pathlen < byte_cnt)
64 : byte_cnt = pathlen;
65 :
66 191298567 : cur_chunk = bp->b_addr;
67 191298567 : if (xfs_has_crc(mp)) {
68 191294837 : 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 191443488 : cur_chunk += sizeof(struct xfs_dsymlink_hdr);
80 : }
81 :
82 382894436 : memcpy(link + offset, cur_chunk, byte_cnt);
83 :
84 191447218 : pathlen -= byte_cnt;
85 191447218 : offset += byte_cnt;
86 :
87 191447218 : xfs_buf_relse(bp);
88 : }
89 191538257 : ASSERT(pathlen == 0);
90 :
91 191538257 : link[ip->i_disk_size] = '\0';
92 191538257 : error = 0;
93 :
94 : out:
95 : return error;
96 : }
97 :
98 : int
99 244590881 : xfs_readlink(
100 : struct xfs_inode *ip,
101 : char *link)
102 : {
103 244590881 : struct xfs_mount *mp = ip->i_mount;
104 244590881 : xfs_fsize_t pathlen;
105 244590881 : int error = -EFSCORRUPTED;
106 :
107 244590881 : trace_xfs_readlink(ip);
108 :
109 488436070 : if (xfs_is_shutdown(mp))
110 : return -EIO;
111 :
112 244217998 : xfs_ilock(ip, XFS_ILOCK_SHARED);
113 :
114 244646868 : pathlen = ip->i_disk_size;
115 244646868 : if (!pathlen)
116 0 : goto out;
117 :
118 244646868 : 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 244646868 : 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 80612983 : if (XFS_IS_CORRUPT(ip->i_mount, !ip->i_df.if_u1.if_data))
132 0 : goto out;
133 :
134 161225966 : memcpy(link, ip->i_df.if_u1.if_data, pathlen + 1);
135 80612983 : error = 0;
136 : } else {
137 164033885 : error = xfs_readlink_bmap_ilocked(ip, link);
138 : }
139 :
140 244807691 : out:
141 244807691 : xfs_iunlock(ip, XFS_ILOCK_SHARED);
142 244807691 : return error;
143 : }
144 :
145 : int
146 295429483 : 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 295429483 : struct xfs_mount *mp = dp->i_mount;
155 295429483 : struct xfs_trans *tp = NULL;
156 295429483 : struct xfs_inode *ip = NULL;
157 295429483 : int error = 0;
158 295429483 : int pathlen;
159 295429483 : bool unlock_dp_on_error = false;
160 295429483 : xfs_fileoff_t first_fsb;
161 295429483 : xfs_filblks_t fs_blocks;
162 295429483 : int nmaps;
163 295429483 : struct xfs_bmbt_irec mval[XFS_SYMLINK_MAPS];
164 295429483 : xfs_daddr_t d;
165 295429483 : const char *cur_chunk;
166 295429483 : int byte_cnt;
167 295429483 : int n;
168 295429483 : struct xfs_buf *bp;
169 295429483 : prid_t prid;
170 295429483 : struct xfs_dquot *udqp = NULL;
171 295429483 : struct xfs_dquot *gdqp = NULL;
172 295429483 : struct xfs_dquot *pdqp = NULL;
173 295429483 : uint resblks;
174 295429483 : xfs_ino_t ino;
175 :
176 295429483 : *ipp = NULL;
177 :
178 295429483 : trace_xfs_symlink(dp, link_name);
179 :
180 590487340 : if (xfs_is_shutdown(mp))
181 : return -EIO;
182 :
183 : /*
184 : * Check component lengths of the target path name.
185 : */
186 295243670 : pathlen = strlen(target_path);
187 295243670 : if (pathlen >= XFS_SYMLINK_MAXLEN) /* total string too long */
188 : return -ENAMETOOLONG;
189 25257645 : ASSERT(pathlen > 0);
190 :
191 25257645 : prid = xfs_get_initial_prid(dp);
192 :
193 : /*
194 : * Make sure that we have allocated dquot(s) on disk.
195 : */
196 25257645 : 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 25762151 : 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 25762146 : if (pathlen <= XFS_LITINO(mp))
208 : fs_blocks = 0;
209 : else
210 17243593 : fs_blocks = xfs_symlink_blocks(mp, pathlen);
211 25761277 : resblks = XFS_SYMLINK_SPACE_RES(mp, link_name->len, fs_blocks);
212 :
213 25761277 : error = xfs_trans_alloc_icreate(mp, &M_RES(mp)->tr_symlink, udqp, gdqp,
214 : pdqp, resblks, &tp);
215 25754718 : if (error)
216 30614 : goto out_release_dquots;
217 :
218 25724104 : xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
219 25721824 : unlock_dp_on_error = true;
220 :
221 : /*
222 : * Check whether the directory allows new symlinks or not.
223 : */
224 25721824 : if (dp->i_diflags & XFS_DIFLAG_NOSYMLINKS) {
225 11 : error = -EPERM;
226 11 : goto out_trans_cancel;
227 : }
228 :
229 : /*
230 : * Allocate an inode for the symlink.
231 : */
232 25721813 : error = xfs_dialloc(&tp, dp->i_ino, S_IFLNK, &ino);
233 25735822 : if (!error)
234 25734730 : error = xfs_init_new_inode(idmap, tp, dp, ino,
235 25734730 : S_IFLNK | (mode & ~S_IFMT), 1, 0, prid,
236 : false, &ip);
237 25716655 : if (error)
238 40 : 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 25716615 : xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);
248 25726566 : unlock_dp_on_error = false;
249 :
250 : /*
251 : * Also attach the dquot(s) to it, if applicable.
252 : */
253 25726566 : xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp, pdqp);
254 :
255 25718362 : resblks -= XFS_IALLOC_SPACE_RES(mp);
256 : /*
257 : * If the symlink will fit into the inode, write it inline.
258 : */
259 25718362 : if (pathlen <= xfs_inode_data_fork_size(ip)) {
260 8502345 : xfs_init_local_fork(ip, XFS_DATA_FORK, target_path, pathlen);
261 :
262 8502721 : ip->i_disk_size = pathlen;
263 8502721 : ip->i_df.if_format = XFS_DINODE_FMT_LOCAL;
264 8502721 : xfs_trans_log_inode(tp, ip, XFS_ILOG_DDATA | XFS_ILOG_CORE);
265 : } else {
266 17216017 : int offset;
267 :
268 17216017 : first_fsb = 0;
269 17216017 : nmaps = XFS_SYMLINK_MAPS;
270 :
271 17216017 : error = xfs_bmapi_write(tp, ip, first_fsb, fs_blocks,
272 : XFS_BMAPI_METADATA, resblks, mval, &nmaps);
273 17192948 : if (error)
274 6 : goto out_trans_cancel;
275 :
276 17192942 : resblks -= fs_blocks;
277 17192942 : ip->i_disk_size = pathlen;
278 17192942 : xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
279 :
280 17192942 : cur_chunk = target_path;
281 17192942 : offset = 0;
282 51635155 : for (n = 0; n < nmaps; n++) {
283 17228690 : char *buf;
284 :
285 17228690 : d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock);
286 17197584 : byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount);
287 17197801 : error = xfs_trans_get_buf(tp, mp->m_ddev_targp, d,
288 17197801 : BTOBB(byte_cnt), 0, &bp);
289 17203220 : if (error)
290 0 : goto out_trans_cancel;
291 17203220 : bp->b_ops = &xfs_symlink_buf_ops;
292 :
293 17203220 : byte_cnt = XFS_SYMLINK_BUF_SPACE(mp, byte_cnt);
294 17203220 : byte_cnt = min(byte_cnt, pathlen);
295 :
296 17203220 : buf = bp->b_addr;
297 17203220 : buf += xfs_symlink_hdr_set(mp, ip->i_ino, offset,
298 : byte_cnt, bp);
299 :
300 34351516 : memcpy(buf, cur_chunk, byte_cnt);
301 :
302 17175758 : cur_chunk += byte_cnt;
303 17175758 : pathlen -= byte_cnt;
304 17175758 : offset += byte_cnt;
305 :
306 17175758 : xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SYMLINK_BUF);
307 17202054 : xfs_trans_log_buf(tp, bp, 0, (buf + byte_cnt - 1) -
308 17202054 : (char *)bp->b_addr);
309 : }
310 17213523 : ASSERT(pathlen == 0);
311 : }
312 25719404 : i_size_write(VFS_I(ip), ip->i_disk_size);
313 :
314 : /*
315 : * Create the directory entry for the symlink.
316 : */
317 25719404 : error = xfs_dir_createname(tp, dp, link_name, ip->i_ino, resblks);
318 25725324 : if (error)
319 0 : goto out_trans_cancel;
320 25725324 : xfs_trans_ichgtime(tp, dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
321 25711120 : 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 25732829 : if (xfs_has_wsync(mp) || xfs_has_dirsync(mp))
329 0 : xfs_trans_set_sync(tp);
330 :
331 25732829 : error = xfs_trans_commit(tp);
332 25699771 : if (error)
333 7 : goto out_release_inode;
334 :
335 25699764 : xfs_qm_dqrele(udqp);
336 25695294 : xfs_qm_dqrele(gdqp);
337 25698608 : xfs_qm_dqrele(pdqp);
338 :
339 25703183 : *ipp = ip;
340 25703183 : return 0;
341 :
342 57 : out_trans_cancel:
343 57 : xfs_trans_cancel(tp);
344 64 : 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 64 : if (ip) {
351 13 : xfs_finish_inode_setup(ip);
352 13 : xfs_irele(ip);
353 : }
354 51 : out_release_dquots:
355 30678 : xfs_qm_dqrele(udqp);
356 30679 : xfs_qm_dqrele(gdqp);
357 30679 : xfs_qm_dqrele(pdqp);
358 :
359 30679 : if (unlock_dp_on_error)
360 51 : 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 16528494 : xfs_inactive_symlink_rmt(
375 : struct xfs_inode *ip)
376 : {
377 16528494 : struct xfs_buf *bp;
378 16528494 : int done;
379 16528494 : int error;
380 16528494 : int i;
381 16528494 : xfs_mount_t *mp;
382 16528494 : xfs_bmbt_irec_t mval[XFS_SYMLINK_MAPS];
383 16528494 : int nmaps;
384 16528494 : int size;
385 16528494 : xfs_trans_t *tp;
386 :
387 16528494 : mp = ip->i_mount;
388 16528494 : 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 16528150 : ASSERT(ip->i_df.if_nextents > 0 && ip->i_df.if_nextents <= 2);
397 :
398 16528150 : error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp);
399 16517184 : if (error)
400 : return error;
401 :
402 16517423 : xfs_ilock(ip, XFS_ILOCK_EXCL);
403 16521834 : 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 16523507 : size = (int)ip->i_disk_size;
412 16523507 : ip->i_disk_size = 0;
413 16523507 : VFS_I(ip)->i_mode = (VFS_I(ip)->i_mode & ~S_IFMT) | S_IFREG;
414 16523507 : xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
415 : /*
416 : * Find the block(s) so we can inval and unmap them.
417 : */
418 16538426 : done = 0;
419 16538426 : nmaps = ARRAY_SIZE(mval);
420 16538426 : error = xfs_bmapi_read(ip, 0, xfs_symlink_blocks(mp, size),
421 : mval, &nmaps, 0);
422 16509718 : if (error)
423 0 : goto error_trans_cancel;
424 : /*
425 : * Invalidate the block(s). No validation is done.
426 : */
427 33053336 : for (i = 0; i < nmaps; i++) {
428 82529418 : error = xfs_trans_get_buf(tp, mp->m_ddev_targp,
429 16510133 : XFS_FSB_TO_DADDR(mp, mval[i].br_startblock),
430 16511422 : XFS_FSB_TO_BB(mp, mval[i].br_blockcount), 0,
431 : &bp);
432 16525425 : if (error)
433 0 : goto error_trans_cancel;
434 16525425 : xfs_trans_binval(tp, bp);
435 : }
436 : /*
437 : * Unmap the dead block(s) to the dfops.
438 : */
439 16541914 : error = xfs_bunmapi(tp, ip, 0, size, 0, nmaps, &done);
440 16527796 : if (error)
441 0 : goto error_trans_cancel;
442 16527796 : 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 16527796 : xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
449 16538366 : error = xfs_trans_commit(tp);
450 16532549 : if (error) {
451 8 : ASSERT(xfs_is_shutdown(mp));
452 4 : goto error_unlock;
453 : }
454 :
455 : /*
456 : * Remove the memory for extent descriptions (just bookkeeping).
457 : */
458 16532545 : if (ip->i_df.if_bytes)
459 0 : xfs_idata_realloc(ip, -ip->i_df.if_bytes, XFS_DATA_FORK);
460 16532545 : ASSERT(ip->i_df.if_bytes == 0);
461 :
462 16532545 : xfs_iunlock(ip, XFS_ILOCK_EXCL);
463 16532545 : return 0;
464 :
465 0 : error_trans_cancel:
466 0 : xfs_trans_cancel(tp);
467 4 : error_unlock:
468 4 : xfs_iunlock(ip, XFS_ILOCK_EXCL);
469 4 : return error;
470 : }
471 :
472 : /*
473 : * xfs_inactive_symlink - free a symlink
474 : */
475 : int
476 24644249 : xfs_inactive_symlink(
477 : struct xfs_inode *ip)
478 : {
479 24644249 : struct xfs_mount *mp = ip->i_mount;
480 24644249 : int pathlen;
481 :
482 24644249 : trace_xfs_inactive_symlink(ip);
483 :
484 49246406 : if (xfs_is_shutdown(mp))
485 : return -EIO;
486 :
487 24623192 : xfs_ilock(ip, XFS_ILOCK_EXCL);
488 24668587 : pathlen = (int)ip->i_disk_size;
489 24668587 : ASSERT(pathlen);
490 :
491 24668587 : 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 24668587 : if (ip->i_df.if_format == XFS_DINODE_FMT_LOCAL) {
504 8139487 : xfs_iunlock(ip, XFS_ILOCK_EXCL);
505 8139487 : return 0;
506 : }
507 :
508 16529100 : xfs_iunlock(ip, XFS_ILOCK_EXCL);
509 :
510 : /* remove the remote symlink */
511 16535258 : return xfs_inactive_symlink_rmt(ip);
512 : }
|