hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/fs/ubifs/io.c
....@@ -1,21 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * This file is part of UBIFS.
34 *
45 * Copyright (C) 2006-2008 Nokia Corporation.
56 * Copyright (C) 2006, 2007 University of Szeged, Hungary
6
- *
7
- * This program is free software; you can redistribute it and/or modify it
8
- * under the terms of the GNU General Public License version 2 as published by
9
- * the Free Software Foundation.
10
- *
11
- * This program is distributed in the hope that it will be useful, but WITHOUT
12
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14
- * more details.
15
- *
16
- * You should have received a copy of the GNU General Public License along with
17
- * this program; if not, write to the Free Software Foundation, Inc., 51
18
- * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
197 *
208 * Authors: Artem Bityutskiy (Битюцкий Артём)
219 * Adrian Hunter
....@@ -377,6 +365,68 @@
377365 return sqnum;
378366 }
379367
368
+void ubifs_init_node(struct ubifs_info *c, void *node, int len, int pad)
369
+{
370
+ struct ubifs_ch *ch = node;
371
+ unsigned long long sqnum = next_sqnum(c);
372
+
373
+ ubifs_assert(c, len >= UBIFS_CH_SZ);
374
+
375
+ ch->magic = cpu_to_le32(UBIFS_NODE_MAGIC);
376
+ ch->len = cpu_to_le32(len);
377
+ ch->group_type = UBIFS_NO_NODE_GROUP;
378
+ ch->sqnum = cpu_to_le64(sqnum);
379
+ ch->padding[0] = ch->padding[1] = 0;
380
+
381
+ if (pad) {
382
+ len = ALIGN(len, 8);
383
+ pad = ALIGN(len, c->min_io_size) - len;
384
+ ubifs_pad(c, node + len, pad);
385
+ }
386
+}
387
+
388
+void ubifs_crc_node(struct ubifs_info *c, void *node, int len)
389
+{
390
+ struct ubifs_ch *ch = node;
391
+ uint32_t crc;
392
+
393
+ crc = crc32(UBIFS_CRC32_INIT, node + 8, len - 8);
394
+ ch->crc = cpu_to_le32(crc);
395
+}
396
+
397
+/**
398
+ * ubifs_prepare_node_hmac - prepare node to be written to flash.
399
+ * @c: UBIFS file-system description object
400
+ * @node: the node to pad
401
+ * @len: node length
402
+ * @hmac_offs: offset of the HMAC in the node
403
+ * @pad: if the buffer has to be padded
404
+ *
405
+ * This function prepares node at @node to be written to the media - it
406
+ * calculates node CRC, fills the common header, and adds proper padding up to
407
+ * the next minimum I/O unit if @pad is not zero. if @hmac_offs is positive then
408
+ * a HMAC is inserted into the node at the given offset.
409
+ *
410
+ * This function returns 0 for success or a negative error code otherwise.
411
+ */
412
+int ubifs_prepare_node_hmac(struct ubifs_info *c, void *node, int len,
413
+ int hmac_offs, int pad)
414
+{
415
+ int err;
416
+
417
+ ubifs_init_node(c, node, len, pad);
418
+
419
+ if (hmac_offs > 0) {
420
+ err = ubifs_node_insert_hmac(c, node, len, hmac_offs);
421
+ if (err)
422
+ return err;
423
+ }
424
+
425
+ ubifs_crc_node(c, node, len);
426
+
427
+ return 0;
428
+}
429
+
380430 /**
381431 * ubifs_prepare_node - prepare node to be written to flash.
382432 * @c: UBIFS file-system description object
....@@ -390,25 +440,11 @@
390440 */
391441 void ubifs_prepare_node(struct ubifs_info *c, void *node, int len, int pad)
392442 {
393
- uint32_t crc;
394
- struct ubifs_ch *ch = node;
395
- unsigned long long sqnum = next_sqnum(c);
396
-
397
- ubifs_assert(c, len >= UBIFS_CH_SZ);
398
-
399
- ch->magic = cpu_to_le32(UBIFS_NODE_MAGIC);
400
- ch->len = cpu_to_le32(len);
401
- ch->group_type = UBIFS_NO_NODE_GROUP;
402
- ch->sqnum = cpu_to_le64(sqnum);
403
- ch->padding[0] = ch->padding[1] = 0;
404
- crc = crc32(UBIFS_CRC32_INIT, node + 8, len - 8);
405
- ch->crc = cpu_to_le32(crc);
406
-
407
- if (pad) {
408
- len = ALIGN(len, 8);
409
- pad = ALIGN(len, c->min_io_size) - len;
410
- ubifs_pad(c, node + len, pad);
411
- }
443
+ /*
444
+ * Deliberately ignore return value since this function can only fail
445
+ * when a hmac offset is given.
446
+ */
447
+ ubifs_prepare_node_hmac(c, node, len, 0, pad);
412448 }
413449
414450 /**
....@@ -810,16 +846,42 @@
810846 */
811847 n = aligned_len >> c->max_write_shift;
812848 if (n) {
813
- n <<= c->max_write_shift;
849
+ int m = n - 1;
850
+
814851 dbg_io("write %d bytes to LEB %d:%d", n, wbuf->lnum,
815852 wbuf->offs);
816
- err = ubifs_leb_write(c, wbuf->lnum, buf + written,
817
- wbuf->offs, n);
853
+
854
+ if (m) {
855
+ /* '(n-1)<<c->max_write_shift < len' is always true. */
856
+ m <<= c->max_write_shift;
857
+ err = ubifs_leb_write(c, wbuf->lnum, buf + written,
858
+ wbuf->offs, m);
859
+ if (err)
860
+ goto out;
861
+ wbuf->offs += m;
862
+ aligned_len -= m;
863
+ len -= m;
864
+ written += m;
865
+ }
866
+
867
+ /*
868
+ * The non-written len of buf may be less than 'n' because
869
+ * parameter 'len' is not 8 bytes aligned, so here we read
870
+ * min(len, n) bytes from buf.
871
+ */
872
+ n = 1 << c->max_write_shift;
873
+ memcpy(wbuf->buf, buf + written, min(len, n));
874
+ if (n > len) {
875
+ ubifs_assert(c, n - len < 8);
876
+ ubifs_pad(c, wbuf->buf + len, n - len);
877
+ }
878
+
879
+ err = ubifs_leb_write(c, wbuf->lnum, wbuf->buf, wbuf->offs, n);
818880 if (err)
819881 goto out;
820882 wbuf->offs += n;
821883 aligned_len -= n;
822
- len -= n;
884
+ len -= min(len, n);
823885 written += n;
824886 }
825887
....@@ -870,6 +932,48 @@
870932 }
871933
872934 /**
935
+ * ubifs_write_node_hmac - write node to the media.
936
+ * @c: UBIFS file-system description object
937
+ * @buf: the node to write
938
+ * @len: node length
939
+ * @lnum: logical eraseblock number
940
+ * @offs: offset within the logical eraseblock
941
+ * @hmac_offs: offset of the HMAC within the node
942
+ *
943
+ * This function automatically fills node magic number, assigns sequence
944
+ * number, and calculates node CRC checksum. The length of the @buf buffer has
945
+ * to be aligned to the minimal I/O unit size. This function automatically
946
+ * appends padding node and padding bytes if needed. Returns zero in case of
947
+ * success and a negative error code in case of failure.
948
+ */
949
+int ubifs_write_node_hmac(struct ubifs_info *c, void *buf, int len, int lnum,
950
+ int offs, int hmac_offs)
951
+{
952
+ int err, buf_len = ALIGN(len, c->min_io_size);
953
+
954
+ dbg_io("LEB %d:%d, %s, length %d (aligned %d)",
955
+ lnum, offs, dbg_ntype(((struct ubifs_ch *)buf)->node_type), len,
956
+ buf_len);
957
+ ubifs_assert(c, lnum >= 0 && lnum < c->leb_cnt && offs >= 0);
958
+ ubifs_assert(c, offs % c->min_io_size == 0 && offs < c->leb_size);
959
+ ubifs_assert(c, !c->ro_media && !c->ro_mount);
960
+ ubifs_assert(c, !c->space_fixup);
961
+
962
+ if (c->ro_error)
963
+ return -EROFS;
964
+
965
+ err = ubifs_prepare_node_hmac(c, buf, len, hmac_offs, 1);
966
+ if (err)
967
+ return err;
968
+
969
+ err = ubifs_leb_write(c, lnum, buf, offs, buf_len);
970
+ if (err)
971
+ ubifs_dump_node(c, buf);
972
+
973
+ return err;
974
+}
975
+
976
+/**
873977 * ubifs_write_node - write node to the media.
874978 * @c: UBIFS file-system description object
875979 * @buf: the node to write
....@@ -886,25 +990,7 @@
886990 int ubifs_write_node(struct ubifs_info *c, void *buf, int len, int lnum,
887991 int offs)
888992 {
889
- int err, buf_len = ALIGN(len, c->min_io_size);
890
-
891
- dbg_io("LEB %d:%d, %s, length %d (aligned %d)",
892
- lnum, offs, dbg_ntype(((struct ubifs_ch *)buf)->node_type), len,
893
- buf_len);
894
- ubifs_assert(c, lnum >= 0 && lnum < c->leb_cnt && offs >= 0);
895
- ubifs_assert(c, offs % c->min_io_size == 0 && offs < c->leb_size);
896
- ubifs_assert(c, !c->ro_media && !c->ro_mount);
897
- ubifs_assert(c, !c->space_fixup);
898
-
899
- if (c->ro_error)
900
- return -EROFS;
901
-
902
- ubifs_prepare_node(c, buf, len, 1);
903
- err = ubifs_leb_write(c, lnum, buf, offs, buf_len);
904
- if (err)
905
- ubifs_dump_node(c, buf);
906
-
907
- return err;
993
+ return ubifs_write_node_hmac(c, buf, len, lnum, offs, -1);
908994 }
909995
910996 /**