ksmbd: send lease break notification on FILE_RENAME_INFORMATION
[platform/kernel/linux-rpi.git] / fs / splice.c
index 3e2a31e..d983d37 100644 (file)
@@ -83,8 +83,7 @@ static bool page_cache_pipe_buf_try_steal(struct pipe_inode_info *pipe,
                 */
                folio_wait_writeback(folio);
 
-               if (folio_has_private(folio) &&
-                   !filemap_release_folio(folio, GFP_KERNEL))
+               if (!filemap_release_folio(folio, GFP_KERNEL))
                        goto out_unlock;
 
                /*
@@ -120,17 +119,17 @@ static void page_cache_pipe_buf_release(struct pipe_inode_info *pipe,
 static int page_cache_pipe_buf_confirm(struct pipe_inode_info *pipe,
                                       struct pipe_buffer *buf)
 {
-       struct page *page = buf->page;
+       struct folio *folio = page_folio(buf->page);
        int err;
 
-       if (!PageUptodate(page)) {
-               lock_page(page);
+       if (!folio_test_uptodate(folio)) {
+               folio_lock(folio);
 
                /*
-                * Page got truncated/unhashed. This will cause a 0-byte
+                * Folio got truncated/unhashed. This will cause a 0-byte
                 * splice, if this is the first page.
                 */
-               if (!page->mapping) {
+               if (!folio->mapping) {
                        err = -ENODATA;
                        goto error;
                }
@@ -138,20 +137,18 @@ static int page_cache_pipe_buf_confirm(struct pipe_inode_info *pipe,
                /*
                 * Uh oh, read-error from disk.
                 */
-               if (!PageUptodate(page)) {
+               if (!folio_test_uptodate(folio)) {
                        err = -EIO;
                        goto error;
                }
 
-               /*
-                * Page is ok afterall, we are done.
-                */
-               unlock_page(page);
+               /* Folio is ok after all, we are done */
+               folio_unlock(folio);
        }
 
        return 0;
 error:
-       unlock_page(page);
+       folio_unlock(folio);
        return err;
 }
 
@@ -1269,10 +1266,8 @@ long do_splice(struct file *in, loff_t *off_in, struct file *out,
                if ((in->f_flags | out->f_flags) & O_NONBLOCK)
                        flags |= SPLICE_F_NONBLOCK;
 
-               return splice_pipe_to_pipe(ipipe, opipe, len, flags);
-       }
-
-       if (ipipe) {
+               ret = splice_pipe_to_pipe(ipipe, opipe, len, flags);
+       } else if (ipipe) {
                if (off_in)
                        return -ESPIPE;
                if (off_out) {
@@ -1297,18 +1292,11 @@ long do_splice(struct file *in, loff_t *off_in, struct file *out,
                ret = do_splice_from(ipipe, out, &offset, len, flags);
                file_end_write(out);
 
-               if (ret > 0)
-                       fsnotify_modify(out);
-
                if (!off_out)
                        out->f_pos = offset;
                else
                        *off_out = offset;
-
-               return ret;
-       }
-
-       if (opipe) {
+       } else if (opipe) {
                if (off_out)
                        return -ESPIPE;
                if (off_in) {
@@ -1324,18 +1312,25 @@ long do_splice(struct file *in, loff_t *off_in, struct file *out,
 
                ret = splice_file_to_pipe(in, opipe, &offset, len, flags);
 
-               if (ret > 0)
-                       fsnotify_access(in);
-
                if (!off_in)
                        in->f_pos = offset;
                else
                        *off_in = offset;
+       } else {
+               ret = -EINVAL;
+       }
 
-               return ret;
+       if (ret > 0) {
+               /*
+                * Generate modify out before access in:
+                * do_splice_from() may've already sent modify out,
+                * and this ensures the events get merged.
+                */
+               fsnotify_modify(out);
+               fsnotify_access(in);
        }
 
-       return -EINVAL;
+       return ret;
 }
 
 static long __do_splice(struct file *in, loff_t __user *off_in,
@@ -1464,6 +1459,9 @@ static long vmsplice_to_user(struct file *file, struct iov_iter *iter,
                pipe_unlock(pipe);
        }
 
+       if (ret > 0)
+               fsnotify_access(file);
+
        return ret;
 }
 
@@ -1493,8 +1491,10 @@ static long vmsplice_to_pipe(struct file *file, struct iov_iter *iter,
        if (!ret)
                ret = iter_to_pipe(iter, pipe, buf_flag);
        pipe_unlock(pipe);
-       if (ret > 0)
+       if (ret > 0) {
                wakeup_pipe_readers(pipe);
+               fsnotify_modify(file);
+       }
        return ret;
 }
 
@@ -1928,6 +1928,11 @@ long do_tee(struct file *in, struct file *out, size_t len, unsigned int flags)
                }
        }
 
+       if (ret > 0) {
+               fsnotify_access(in);
+               fsnotify_modify(out);
+       }
+
        return ret;
 }