Logo Search packages:      
Sourcecode: s3ql version File versions  Download package

def s3ql::block_cache::BlockCache::remove (   self,
  inode,
  start_no,
  end_no = None 
)
Remove blocks for `inode`

If `end_no` is not specified, remove just the `start_no` block.
Otherwise removes all blocks from `start_no` to, but not including,
 `end_no`. 

This method releases the global lock.

Note: if `get` and `remove` are called concurrently, then it
is possible that a block that has been requested with `get` and
passed to `remove` for deletion will not be deleted.

Definition at line 336 of file block_cache.py.

                                                  :
        """Remove blocks for `inode`
        
        If `end_no` is not specified, remove just the `start_no` block.
        Otherwise removes all blocks from `start_no` to, but not including,
         `end_no`. 
        
        This method releases the global lock.
        
        Note: if `get` and `remove` are called concurrently, then it
        is possible that a block that has been requested with `get` and
        passed to `remove` for deletion will not be deleted.
        """

        log.debug('remove(inode=%d, start=%d, end=%s): start',
                  inode, start_no, end_no)

        if end_no is None:
            end_no = start_no + 1
            
        for blockno in range(start_no, end_no):
            # We can't use self.mlock here to prevent simultaneous retrieval
            # of the block with get(), because this could deadlock
            if (inode, blockno) in self.cache:
                # Type inference fails here
                #pylint: disable-msg=E1103
                el = self.cache.pop((inode, blockno))

                self.size -= os.fstat(el.fileno()).st_size
                el.close()
                if el.dirty:
                    os.unlink(el.name + '.d')
                else:
                    os.unlink(el.name)

                if el.obj_id is None:
                    log.debug('remove(inode=%d, blockno=%d): block only in cache',
                              inode, blockno)
                    continue

                log.debug('remove(inode=%d, blockno=%d): block in cache and db', inode, blockno)
                obj_id = el.obj_id

            else:
                try:
                    obj_id = self.db.get_val('SELECT obj_id FROM blocks WHERE inode=? '
                                          'AND blockno = ?', (inode, blockno))
                except NoSuchRowError:
                    log.debug('remove(inode=%d, blockno=%d): block does not exist',
                              inode, blockno)
                    continue

                log.debug('remove(inode=%d, blockno=%d): block only in db ', inode, blockno)

            self.db.execute('DELETE FROM blocks WHERE inode=? AND blockno=?',
                         (inode, blockno))
                
            refcount = self.db.get_val('SELECT refcount FROM objects WHERE id=?', (obj_id,))
            if refcount > 1:
                log.debug('remove(inode=%d, blockno=%d): decreasing refcount for object %d',
                          inode, blockno, obj_id)                    
                self.db.execute('UPDATE objects SET refcount=refcount-1 WHERE id=?',
                             (obj_id,))
                to_delete = False
            else:
                log.debug('remove(inode=%d, blockno=%d): deleting object %d',
                          inode, blockno, obj_id)     
                self.db.execute('DELETE FROM objects WHERE id=?', (obj_id,))
                to_delete = True
        
            if to_delete:
                try:
                    # Releases global lock:
                    self.removal_queue.add_thread(RemoveThread(obj_id, self.bucket,
                                                               (inode, blockno),
                                                               self.upload_manager))
                except EmbeddedException as exc:
                    exc = exc.exc_info[1]
                    if isinstance(exc, NoSuchObject):
                        log.warn('Backend seems to have lost object %s', exc.key)
                        self.encountered_errors = True
                    else:
                        raise

        log.debug('remove(inode=%d, start=%d, end=%s): end',
                  inode, start_no, end_no)


Generated by  Doxygen 1.6.0   Back to index