Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ceph: supply snapshot context in ceph_zero_partial_object()

The ceph_zero_partial_object function was missing proper snapshot
context for its OSD write operations, which could lead to data
inconsistencies in snapshots.

Reproducer:
../src/vstart.sh --new -x --localhost --bluestore
./bin/ceph auth caps client.fs_a mds 'allow rwps fsname=a' mon 'allow r fsname=a' osd 'allow rw tag cephfs data=a'
mount -t ceph fs_a@.a=/ /mnt/mycephfs/ -o conf=./ceph.conf
dd if=/dev/urandom of=/mnt/mycephfs/foo bs=64K count=1
mkdir /mnt/mycephfs/.snap/snap1
md5sum /mnt/mycephfs/.snap/snap1/foo
fallocate -p -o 0 -l 4096 /mnt/mycephfs/foo
echo 3 > /proc/sys/vm/drop/caches
md5sum /mnt/mycephfs/.snap/snap1/foo # get different md5sum!!

Cc: stable@vger.kernel.org
Fixes: ad7a60de882ac ("ceph: punch hole support")
Signed-off-by: ethanwu <ethanwu@synology.com>
Reviewed-by: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com>
Tested-by: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>

authored by

ethanwu and committed by
Ilya Dryomov
f16bd3fa 8356b4b1

+16 -1
+16 -1
fs/ceph/file.c
··· 2568 2568 struct ceph_inode_info *ci = ceph_inode(inode); 2569 2569 struct ceph_fs_client *fsc = ceph_inode_to_fs_client(inode); 2570 2570 struct ceph_osd_request *req; 2571 + struct ceph_snap_context *snapc; 2571 2572 int ret = 0; 2572 2573 loff_t zero = 0; 2573 2574 int op; ··· 2583 2582 op = CEPH_OSD_OP_ZERO; 2584 2583 } 2585 2584 2585 + spin_lock(&ci->i_ceph_lock); 2586 + if (__ceph_have_pending_cap_snap(ci)) { 2587 + struct ceph_cap_snap *capsnap = 2588 + list_last_entry(&ci->i_cap_snaps, 2589 + struct ceph_cap_snap, 2590 + ci_item); 2591 + snapc = ceph_get_snap_context(capsnap->context); 2592 + } else { 2593 + BUG_ON(!ci->i_head_snapc); 2594 + snapc = ceph_get_snap_context(ci->i_head_snapc); 2595 + } 2596 + spin_unlock(&ci->i_ceph_lock); 2597 + 2586 2598 req = ceph_osdc_new_request(&fsc->client->osdc, &ci->i_layout, 2587 2599 ceph_vino(inode), 2588 2600 offset, length, 2589 2601 0, 1, op, 2590 2602 CEPH_OSD_FLAG_WRITE, 2591 - NULL, 0, 0, false); 2603 + snapc, 0, 0, false); 2592 2604 if (IS_ERR(req)) { 2593 2605 ret = PTR_ERR(req); 2594 2606 goto out; ··· 2615 2601 ceph_osdc_put_request(req); 2616 2602 2617 2603 out: 2604 + ceph_put_snap_context(snapc); 2618 2605 return ret; 2619 2606 } 2620 2607