@@ -5594,6 +5594,14 @@ struct parent_image_info {
5594
5594
u64 overlap ;
5595
5595
};
5596
5596
5597
+ static void rbd_parent_info_cleanup (struct parent_image_info * pii )
5598
+ {
5599
+ kfree (pii -> pool_ns );
5600
+ kfree (pii -> image_id );
5601
+
5602
+ memset (pii , 0 , sizeof (* pii ));
5603
+ }
5604
+
5597
5605
/*
5598
5606
* The caller is responsible for @pii.
5599
5607
*/
@@ -5663,6 +5671,9 @@ static int __get_parent_info(struct rbd_device *rbd_dev,
5663
5671
if (pii -> has_overlap )
5664
5672
ceph_decode_64_safe (& p , end , pii -> overlap , e_inval );
5665
5673
5674
+ dout ("%s pool_id %llu pool_ns %s image_id %s snap_id %llu has_overlap %d overlap %llu\n" ,
5675
+ __func__ , pii -> pool_id , pii -> pool_ns , pii -> image_id , pii -> snap_id ,
5676
+ pii -> has_overlap , pii -> overlap );
5666
5677
return 0 ;
5667
5678
5668
5679
e_inval :
@@ -5701,14 +5712,17 @@ static int __get_parent_info_legacy(struct rbd_device *rbd_dev,
5701
5712
pii -> has_overlap = true;
5702
5713
ceph_decode_64_safe (& p , end , pii -> overlap , e_inval );
5703
5714
5715
+ dout ("%s pool_id %llu pool_ns %s image_id %s snap_id %llu has_overlap %d overlap %llu\n" ,
5716
+ __func__ , pii -> pool_id , pii -> pool_ns , pii -> image_id , pii -> snap_id ,
5717
+ pii -> has_overlap , pii -> overlap );
5704
5718
return 0 ;
5705
5719
5706
5720
e_inval :
5707
5721
return - EINVAL ;
5708
5722
}
5709
5723
5710
- static int get_parent_info (struct rbd_device * rbd_dev ,
5711
- struct parent_image_info * pii )
5724
+ static int rbd_dev_v2_parent_info (struct rbd_device * rbd_dev ,
5725
+ struct parent_image_info * pii )
5712
5726
{
5713
5727
struct page * req_page , * reply_page ;
5714
5728
void * p ;
@@ -5736,7 +5750,7 @@ static int get_parent_info(struct rbd_device *rbd_dev,
5736
5750
return ret ;
5737
5751
}
5738
5752
5739
- static int rbd_dev_v2_parent_info (struct rbd_device * rbd_dev )
5753
+ static int rbd_dev_setup_parent (struct rbd_device * rbd_dev )
5740
5754
{
5741
5755
struct rbd_spec * parent_spec ;
5742
5756
struct parent_image_info pii = { 0 };
@@ -5746,37 +5760,12 @@ static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev)
5746
5760
if (!parent_spec )
5747
5761
return - ENOMEM ;
5748
5762
5749
- ret = get_parent_info (rbd_dev , & pii );
5763
+ ret = rbd_dev_v2_parent_info (rbd_dev , & pii );
5750
5764
if (ret )
5751
5765
goto out_err ;
5752
5766
5753
- dout ("%s pool_id %llu pool_ns %s image_id %s snap_id %llu has_overlap %d overlap %llu\n" ,
5754
- __func__ , pii .pool_id , pii .pool_ns , pii .image_id , pii .snap_id ,
5755
- pii .has_overlap , pii .overlap );
5756
-
5757
- if (pii .pool_id == CEPH_NOPOOL || !pii .has_overlap ) {
5758
- /*
5759
- * Either the parent never existed, or we have
5760
- * record of it but the image got flattened so it no
5761
- * longer has a parent. When the parent of a
5762
- * layered image disappears we immediately set the
5763
- * overlap to 0. The effect of this is that all new
5764
- * requests will be treated as if the image had no
5765
- * parent.
5766
- *
5767
- * If !pii.has_overlap, the parent image spec is not
5768
- * applicable. It's there to avoid duplication in each
5769
- * snapshot record.
5770
- */
5771
- if (rbd_dev -> parent_overlap ) {
5772
- rbd_dev -> parent_overlap = 0 ;
5773
- rbd_dev_parent_put (rbd_dev );
5774
- pr_info ("%s: clone image has been flattened\n" ,
5775
- rbd_dev -> disk -> disk_name );
5776
- }
5777
-
5767
+ if (pii .pool_id == CEPH_NOPOOL || !pii .has_overlap )
5778
5768
goto out ; /* No parent? No problem. */
5779
- }
5780
5769
5781
5770
/* The ceph file layout needs to fit pool id in 32 bits */
5782
5771
@@ -5788,46 +5777,34 @@ static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev)
5788
5777
}
5789
5778
5790
5779
/*
5791
- * The parent won't change (except when the clone is
5792
- * flattened, already handled that). So we only need to
5793
- * record the parent spec we have not already done so.
5780
+ * The parent won't change except when the clone is flattened,
5781
+ * so we only need to record the parent image spec once.
5794
5782
*/
5795
- if (!rbd_dev -> parent_spec ) {
5796
- parent_spec -> pool_id = pii .pool_id ;
5797
- if (pii .pool_ns && * pii .pool_ns ) {
5798
- parent_spec -> pool_ns = pii .pool_ns ;
5799
- pii .pool_ns = NULL ;
5800
- }
5801
- parent_spec -> image_id = pii .image_id ;
5802
- pii .image_id = NULL ;
5803
- parent_spec -> snap_id = pii .snap_id ;
5804
-
5805
- rbd_dev -> parent_spec = parent_spec ;
5806
- parent_spec = NULL ; /* rbd_dev now owns this */
5783
+ parent_spec -> pool_id = pii .pool_id ;
5784
+ if (pii .pool_ns && * pii .pool_ns ) {
5785
+ parent_spec -> pool_ns = pii .pool_ns ;
5786
+ pii .pool_ns = NULL ;
5807
5787
}
5788
+ parent_spec -> image_id = pii .image_id ;
5789
+ pii .image_id = NULL ;
5790
+ parent_spec -> snap_id = pii .snap_id ;
5791
+
5792
+ rbd_assert (!rbd_dev -> parent_spec );
5793
+ rbd_dev -> parent_spec = parent_spec ;
5794
+ parent_spec = NULL ; /* rbd_dev now owns this */
5808
5795
5809
5796
/*
5810
- * We always update the parent overlap. If it's zero we issue
5811
- * a warning, as we will proceed as if there was no parent.
5797
+ * Record the parent overlap. If it's zero, issue a warning as
5798
+ * we will proceed as if there is no parent.
5812
5799
*/
5813
- if (!pii .overlap ) {
5814
- if (parent_spec ) {
5815
- /* refresh, careful to warn just once */
5816
- if (rbd_dev -> parent_overlap )
5817
- rbd_warn (rbd_dev ,
5818
- "clone now standalone (overlap became 0)" );
5819
- } else {
5820
- /* initial probe */
5821
- rbd_warn (rbd_dev , "clone is standalone (overlap 0)" );
5822
- }
5823
- }
5800
+ if (!pii .overlap )
5801
+ rbd_warn (rbd_dev , "clone is standalone (overlap 0)" );
5824
5802
rbd_dev -> parent_overlap = pii .overlap ;
5825
5803
5826
5804
out :
5827
5805
ret = 0 ;
5828
5806
out_err :
5829
- kfree (pii .pool_ns );
5830
- kfree (pii .image_id );
5807
+ rbd_parent_info_cleanup (& pii );
5831
5808
rbd_spec_put (parent_spec );
5832
5809
return ret ;
5833
5810
}
@@ -6977,7 +6954,7 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth)
6977
6954
}
6978
6955
6979
6956
if (rbd_dev -> header .features & RBD_FEATURE_LAYERING ) {
6980
- ret = rbd_dev_v2_parent_info (rbd_dev );
6957
+ ret = rbd_dev_setup_parent (rbd_dev );
6981
6958
if (ret )
6982
6959
goto err_out_probe ;
6983
6960
}
@@ -7026,9 +7003,47 @@ static void rbd_dev_update_header(struct rbd_device *rbd_dev,
7026
7003
}
7027
7004
}
7028
7005
7006
+ static void rbd_dev_update_parent (struct rbd_device * rbd_dev ,
7007
+ struct parent_image_info * pii )
7008
+ {
7009
+ if (pii -> pool_id == CEPH_NOPOOL || !pii -> has_overlap ) {
7010
+ /*
7011
+ * Either the parent never existed, or we have
7012
+ * record of it but the image got flattened so it no
7013
+ * longer has a parent. When the parent of a
7014
+ * layered image disappears we immediately set the
7015
+ * overlap to 0. The effect of this is that all new
7016
+ * requests will be treated as if the image had no
7017
+ * parent.
7018
+ *
7019
+ * If !pii.has_overlap, the parent image spec is not
7020
+ * applicable. It's there to avoid duplication in each
7021
+ * snapshot record.
7022
+ */
7023
+ if (rbd_dev -> parent_overlap ) {
7024
+ rbd_dev -> parent_overlap = 0 ;
7025
+ rbd_dev_parent_put (rbd_dev );
7026
+ pr_info ("%s: clone has been flattened\n" ,
7027
+ rbd_dev -> disk -> disk_name );
7028
+ }
7029
+ } else {
7030
+ rbd_assert (rbd_dev -> parent_spec );
7031
+
7032
+ /*
7033
+ * Update the parent overlap. If it became zero, issue
7034
+ * a warning as we will proceed as if there is no parent.
7035
+ */
7036
+ if (!pii -> overlap && rbd_dev -> parent_overlap )
7037
+ rbd_warn (rbd_dev ,
7038
+ "clone has become standalone (overlap 0)" );
7039
+ rbd_dev -> parent_overlap = pii -> overlap ;
7040
+ }
7041
+ }
7042
+
7029
7043
static int rbd_dev_refresh (struct rbd_device * rbd_dev )
7030
7044
{
7031
7045
struct rbd_image_header header = { 0 };
7046
+ struct parent_image_info pii = { 0 };
7032
7047
u64 mapping_size ;
7033
7048
int ret ;
7034
7049
@@ -7044,12 +7059,14 @@ static int rbd_dev_refresh(struct rbd_device *rbd_dev)
7044
7059
* mapped image getting flattened.
7045
7060
*/
7046
7061
if (rbd_dev -> parent ) {
7047
- ret = rbd_dev_v2_parent_info (rbd_dev );
7062
+ ret = rbd_dev_v2_parent_info (rbd_dev , & pii );
7048
7063
if (ret )
7049
7064
goto out ;
7050
7065
}
7051
7066
7052
7067
rbd_dev_update_header (rbd_dev , & header );
7068
+ if (rbd_dev -> parent )
7069
+ rbd_dev_update_parent (rbd_dev , & pii );
7053
7070
7054
7071
rbd_assert (!rbd_is_snap (rbd_dev ));
7055
7072
rbd_dev -> mapping .size = rbd_dev -> header .image_size ;
@@ -7059,6 +7076,7 @@ static int rbd_dev_refresh(struct rbd_device *rbd_dev)
7059
7076
if (!ret && mapping_size != rbd_dev -> mapping .size )
7060
7077
rbd_dev_update_size (rbd_dev );
7061
7078
7079
+ rbd_parent_info_cleanup (& pii );
7062
7080
rbd_image_header_cleanup (& header );
7063
7081
return ret ;
7064
7082
}
0 commit comments