Merge branch 'polarfire/fixes' into arm/fixes
[platform/kernel/linux-starfive.git] / fs / ubifs / io.c
index 789a781..1607a3c 100644 (file)
@@ -854,16 +854,42 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len)
         */
        n = aligned_len >> c->max_write_shift;
        if (n) {
-               n <<= c->max_write_shift;
+               int m = n - 1;
+
                dbg_io("write %d bytes to LEB %d:%d", n, wbuf->lnum,
                       wbuf->offs);
-               err = ubifs_leb_write(c, wbuf->lnum, buf + written,
-                                     wbuf->offs, n);
+
+               if (m) {
+                       /* '(n-1)<<c->max_write_shift < len' is always true. */
+                       m <<= c->max_write_shift;
+                       err = ubifs_leb_write(c, wbuf->lnum, buf + written,
+                                             wbuf->offs, m);
+                       if (err)
+                               goto out;
+                       wbuf->offs += m;
+                       aligned_len -= m;
+                       len -= m;
+                       written += m;
+               }
+
+               /*
+                * The non-written len of buf may be less than 'n' because
+                * parameter 'len' is not 8 bytes aligned, so here we read
+                * min(len, n) bytes from buf.
+                */
+               n = 1 << c->max_write_shift;
+               memcpy(wbuf->buf, buf + written, min(len, n));
+               if (n > len) {
+                       ubifs_assert(c, n - len < 8);
+                       ubifs_pad(c, wbuf->buf + len, n - len);
+               }
+
+               err = ubifs_leb_write(c, wbuf->lnum, wbuf->buf, wbuf->offs, n);
                if (err)
                        goto out;
                wbuf->offs += n;
                aligned_len -= n;
-               len -= n;
+               len -= min(len, n);
                written += n;
        }