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:
Коммит
916a3b0fc1
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче