6 cifs/smb3 fixes, 3 for stable. Fixes xfstests 451, 313 and 316

-----BEGIN PGP SIGNATURE-----
 
 iQGzBAABCgAdFiEE6fsu8pdIjtWE/DpLiiy9cAdyT1EFAl73SpUACgkQiiy9cAdy
 T1EseAwAkwkY8r/7LbNDnil+xQivdCfxuc+FCYXpw3HBvR/Zfjb+n/01RIpJoJw7
 kl6MyFUBALrNFY6DvhsNErn7cP9O5Fjg73AfDfE2ySG4N+xZt+EcbbNZ6MtWwdQQ
 a+ZzelGkT1lg+x4Xzz6oy9eWjvHPu6V9e8ycWjl2uRc7I19ze9NinV0rWOp80DAN
 uiVEZo/5f28qTYIVP9rFayKN4TcOQYYRYLukP9zH9s0EBvLYQHGefvE8f01iLdm4
 JyDi/4hmGIS4e7IaROImX25DKxPQTVUytjhmxHdmjg1Or0O3WMSr7zLWauJNn1G8
 /820ec/CgBLtqpD6Y9vUar01+U3Q7Qms/UrEwx+WVVpZPDFVNKDfd6aLlj+UCJeQ
 PHERRVKdHMyz5iaqY4hZhS90uizt4mHAmoNf+YcbjdaiBvebqaAuo/foIwadYBEm
 1ZGevYUIt3cpvbAIv/I3OSrTSvY1/OQZmkHj5IZ0iZXdJaMeOhgrXYyIeL95aJEU
 d6x8VYpI
 =5BTi
 -----END PGP SIGNATURE-----

Merge tag '5.8-rc2-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6

Pull cifs fixes from Steve French:
 "Six cifs/smb3 fixes, three of them for stable.

  Fixes xfstests 451, 313 and 316"

* tag '5.8-rc2-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6:
  cifs: misc: Use array_size() in if-statement controlling expression
  cifs: update ctime and mtime during truncate
  cifs/smb3: Fix data inconsistent when punch hole
  cifs/smb3: Fix data inconsistent when zero file range
  cifs: Fix double add page to memcg when cifs_readpages
  cifs: Fix cached_fid refcnt leak in open_shroot
This commit is contained in:
Linus Torvalds 2020-06-27 15:24:04 -07:00
Родитель 3cd1c5d582 bf1028a41e
Коммит 916a3b0fc1
4 изменённых файлов: 35 добавлений и 13 удалений

Просмотреть файл

@ -4336,7 +4336,8 @@ readpages_get_pages(struct address_space *mapping, struct list_head *page_list,
break;
__SetPageLocked(page);
if (add_to_page_cache_locked(page, mapping, page->index, gfp)) {
rc = add_to_page_cache_locked(page, mapping, page->index, gfp);
if (rc) {
__ClearPageLocked(page);
break;
}
@ -4352,6 +4353,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
struct list_head *page_list, unsigned num_pages)
{
int rc;
int err = 0;
struct list_head tmplist;
struct cifsFileInfo *open_file = file->private_data;
struct cifs_sb_info *cifs_sb = CIFS_FILE_SB(file);
@ -4396,7 +4398,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
* the order of declining indexes. When we put the pages in
* the rdata->pages, then we want them in increasing order.
*/
while (!list_empty(page_list)) {
while (!list_empty(page_list) && !err) {
unsigned int i, nr_pages, bytes, rsize;
loff_t offset;
struct page *page, *tpage;
@ -4429,9 +4431,10 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
return 0;
}
rc = readpages_get_pages(mapping, page_list, rsize, &tmplist,
nr_pages = 0;
err = readpages_get_pages(mapping, page_list, rsize, &tmplist,
&nr_pages, &offset, &bytes);
if (rc) {
if (!nr_pages) {
add_credits_and_wake_if(server, credits, 0);
break;
}

Просмотреть файл

@ -2535,6 +2535,15 @@ set_size_out:
if (rc == 0) {
cifsInode->server_eof = attrs->ia_size;
cifs_setsize(inode, attrs->ia_size);
/*
* The man page of truncate says if the size changed,
* then the st_ctime and st_mtime fields for the file
* are updated.
*/
attrs->ia_ctime = attrs->ia_mtime = current_time(inode);
attrs->ia_valid |= ATTR_CTIME | ATTR_MTIME;
cifs_truncate_page(inode->i_mapping, inode->i_size);
}

Просмотреть файл

@ -844,28 +844,26 @@ setup_aio_ctx_iter(struct cifs_aio_ctx *ctx, struct iov_iter *iter, int rw)
struct bio_vec *bv = NULL;
if (iov_iter_is_kvec(iter)) {
memcpy(&ctx->iter, iter, sizeof(struct iov_iter));
memcpy(&ctx->iter, iter, sizeof(*iter));
ctx->len = count;
iov_iter_advance(iter, count);
return 0;
}
if (max_pages * sizeof(struct bio_vec) <= CIFS_AIO_KMALLOC_LIMIT)
bv = kmalloc_array(max_pages, sizeof(struct bio_vec),
GFP_KERNEL);
if (array_size(max_pages, sizeof(*bv)) <= CIFS_AIO_KMALLOC_LIMIT)
bv = kmalloc_array(max_pages, sizeof(*bv), GFP_KERNEL);
if (!bv) {
bv = vmalloc(array_size(max_pages, sizeof(struct bio_vec)));
bv = vmalloc(array_size(max_pages, sizeof(*bv)));
if (!bv)
return -ENOMEM;
}
if (max_pages * sizeof(struct page *) <= CIFS_AIO_KMALLOC_LIMIT)
pages = kmalloc_array(max_pages, sizeof(struct page *),
GFP_KERNEL);
if (array_size(max_pages, sizeof(*pages)) <= CIFS_AIO_KMALLOC_LIMIT)
pages = kmalloc_array(max_pages, sizeof(*pages), GFP_KERNEL);
if (!pages) {
pages = vmalloc(array_size(max_pages, sizeof(struct page *)));
pages = vmalloc(array_size(max_pages, sizeof(*pages)));
if (!pages) {
kvfree(bv);
return -ENOMEM;

Просмотреть файл

@ -763,6 +763,7 @@ int open_shroot(unsigned int xid, struct cifs_tcon *tcon,
/* close extra handle outside of crit sec */
SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
}
rc = 0;
goto oshr_free;
}
@ -3187,6 +3188,11 @@ static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon,
trace_smb3_zero_enter(xid, cfile->fid.persistent_fid, tcon->tid,
ses->Suid, offset, len);
/*
* We zero the range through ioctl, so we need remove the page caches
* first, otherwise the data may be inconsistent with the server.
*/
truncate_pagecache_range(inode, offset, offset + len - 1);
/* if file not oplocked can't be sure whether asking to extend size */
if (!CIFS_CACHE_READ(cifsi))
@ -3253,6 +3259,12 @@ static long smb3_punch_hole(struct file *file, struct cifs_tcon *tcon,
return rc;
}
/*
* We implement the punch hole through ioctl, so we need remove the page
* caches first, otherwise the data may be inconsistent with the server.
*/
truncate_pagecache_range(inode, offset, offset + len - 1);
cifs_dbg(FYI, "Offset %lld len %lld\n", offset, len);
fsctl_buf.FileOffset = cpu_to_le64(offset);