@@ -215,30 +215,66 @@ def enforce_versioning(self, req):
215
215
# first and an update of versioning mode may not be detected.
216
216
memcache = getattr (self .app , 'memcache' , None ) or \
217
217
req .environ .get ('swift.cache' )
218
- if memcache is None :
219
- return None
220
218
221
219
key = "/" .join (("versioning" , self .account_name , root_container ))
222
- val = memcache .get (key )
223
- if val is not None :
224
- if val != '' :
225
- req .headers [FORCEVERSIONING_HEADER ] = val
220
+ value = memcache .get (key )
221
+ if value is not None :
222
+ if value :
223
+ req .headers [FORCEVERSIONING_HEADER ] = value
226
224
return
227
225
228
226
oio_headers = {REQID_HEADER : self .trans_id }
229
- oio_cache = req .environ .get ('oio.cache' )
230
227
perfdata = req .environ .get ('oio.perfdata' )
231
228
try :
232
229
meta = self .app .storage .container_get_properties (
233
230
self .account_name , root_container , headers = oio_headers ,
234
- cache = oio_cache , perfdata = perfdata )
231
+ perfdata = perfdata )
232
+ except exceptions .NoSuchContainer :
233
+ raise HTTPNotFound (request = req )
234
+
235
+ value = meta ['system' ].get ('sys.m2.policy.version' )
236
+ memcache .set (key , value or '' )
237
+ if value :
238
+ req .headers [FORCEVERSIONING_HEADER ] = value
239
+
240
+ def use_bucket_storage_policy (self , req ):
241
+ """
242
+ Enforce the storage policy mode of a container just before executing
243
+ an object operation. This is useful when the current object is not
244
+ stored in the "main" container but in a shard,
245
+ where the storage policy mode may not have been set yet.
246
+ """
247
+ if not self .app .use_bucket_storage_policy :
248
+ return None
249
+
250
+ root_container = req .headers .get (BUCKET_NAME_HEADER )
251
+ if root_container is None :
252
+ return None
253
+ if root_container .endswith (MULTIUPLOAD_SUFFIX ):
254
+ root_container = root_container [:- len (MULTIUPLOAD_SUFFIX )]
255
+
256
+ # We can't use _get_info_from_caches as it would use local worker cache
257
+ # first and an update of storage policy mode may not be detected.
258
+ memcache = getattr (self .app , 'memcache' , None ) or \
259
+ req .environ .get ('swift.cache' )
260
+
261
+ key = "/" .join (("policy" , self .account_name , root_container ))
262
+ value = memcache .get (key )
263
+ if value is not None :
264
+ return value or None
265
+
266
+ oio_headers = {REQID_HEADER : self .trans_id }
267
+ perfdata = req .environ .get ('oio.perfdata' )
268
+ try :
269
+ meta = self .app .storage .container_get_properties (
270
+ self .account_name , root_container , headers = oio_headers ,
271
+ perfdata = perfdata )
235
272
except exceptions .NoSuchContainer :
236
273
raise HTTPNotFound (request = req )
274
+ value = meta ['system' ].get ('sys.m2.policy.storage' )
237
275
238
- val = meta ['system' ].get ('sys.m2.policy.version' , '' )
239
- memcache .set (key , val )
240
- if val :
241
- req .headers [FORCEVERSIONING_HEADER ] = val
276
+ memcache .set (key , value or '' )
277
+ return value
242
278
243
279
def get_object_head_resp (self , req ):
244
280
storage = self .app .storage
@@ -647,15 +683,15 @@ def _object_create(self, account, container, **kwargs):
647
683
def _store_object (self , req , data_source , headers ):
648
684
content_type = req .headers .get ('content-type' , 'octet/stream' )
649
685
policy = None
650
- container_info = self .container_info (self .account_name ,
651
- self .container_name , req )
652
686
if 'X-Oio-Storage-Policy' in req .headers :
653
687
policy = req .headers .get ('X-Oio-Storage-Policy' )
654
688
if not self .app .POLICIES .get_by_name (policy ):
655
689
raise HTTPBadRequest (
656
690
"invalid policy '%s', must be in %s" %
657
691
(policy , self .app .POLICIES .by_name .keys ()))
658
692
else :
693
+ container_info = self .container_info (self .account_name ,
694
+ self .container_name , req )
659
695
try :
660
696
policy_index = int (
661
697
req .headers .get ('X-Backend-Storage-Policy-Index' ,
@@ -665,6 +701,8 @@ def _store_object(self, req, data_source, headers):
665
701
if policy_index != 0 :
666
702
policy = self .app .POLICIES .get_by_index (policy_index ).name
667
703
else :
704
+ policy = self .use_bucket_storage_policy (req )
705
+ if policy is None :
668
706
content_length = int (req .headers .get ('content-length' , 0 ))
669
707
policy = self ._get_auto_policy_from_size (content_length )
670
708
0 commit comments