Esempio n. 1
0
// update a file's manifest, in response to a remote call 
// return 0 on success
// return -ENOENT if not found
// return -ESTALE if not local
// return -errno on error 
// NOTE: the permissions will already have been checked by the server
static int UG_impl_manifest_patch( struct SG_gateway* gateway, struct SG_request_data* reqdat, struct SG_manifest* write_delta, void* cls ) {
   
   int rc = 0;
   int ref_rc = 0;
   struct fskit_entry* fent = NULL;
   struct UG_state* ug = (struct UG_state*)SG_gateway_cls( gateway );
   
   struct fskit_core* fs = UG_state_fs( ug );
   struct UG_inode* inode = NULL;
   
   struct ms_client* ms = SG_gateway_ms( gateway );
   uint64_t volume_id = ms_client_get_volume_id( ms );

   rc = UG_consistency_path_ensure_fresh( gateway, reqdat->fs_path );
   if( rc != 0 ) {
      SG_error("UG_consistency_path_ensure_fresh('%s') rc = %d\n", reqdat->fs_path, rc );
      return rc;
   }

   rc = UG_consistency_manifest_ensure_fresh( gateway, reqdat->fs_path );
   if( rc != 0 ) {
      SG_error("UG_consistency_manifest_ensure_fresh('%s') rc = %d\n", reqdat->fs_path, rc );
      return rc;
   }
   
   // look up 
   fent = fskit_entry_resolve_path( fs, reqdat->fs_path, reqdat->user_id, volume_id, true, &rc );
   if( fent == NULL ) {
      
      return rc;
   }
   
   inode = (struct UG_inode*)fskit_entry_get_user_data( fent );
   
   // must be coordinated by us 
   if( UG_inode_coordinator_id( inode ) != SG_gateway_id( gateway ) ) {
      
      fskit_entry_unlock( fent );
      return -ESTALE;
   }
   
   // update the manifest 
   fskit_entry_ref_entry( fent );
   rc = UG_write_patch_manifest( gateway, reqdat, inode, write_delta );
   
   fskit_entry_unlock( fent );

   ref_rc = fskit_entry_unref( fs, reqdat->fs_path, fent );
   if( ref_rc != 0 ) {
      SG_warn("fskit_entry_unref('%s') rc = %d\n", reqdat->fs_path, rc );
   }
   
   return rc;
}
Esempio n. 2
0
File: fs.cpp Progetto: 8l/vdev
// sync: sync as usual
// NOTE: since this is backed by FUSE, this handler will only be called for regular files
int vdevfs_sync( struct fskit_core* core, struct fskit_match_group* grp, struct fskit_entry* fent ) {
   
   void* user_data = fskit_entry_get_user_data( fent );
   
   // careful...
   int fd = 0;
   memcpy( &fd, &user_data, 4 );
   
   int rc = 0;
   
   rc = fsync( fd );
   if( rc < 0 ) {
      
      rc = -errno;
      vdev_error("fsync(%d '%s') rc = %d\n", fd, grp->path, rc );
      
      return rc;
   }
   
   return rc;
}
Esempio n. 3
0
// stat a file's block--build a manifest request, and set its mode
// return 0 on success 
// return -ESTALE if the inode is not local 
// return -ENOENT if we don't have it
// return -ENOMEM on OOM
// return -errno on error 
static int UG_impl_stat_block( struct SG_gateway* gateway, struct SG_request_data* reqdat, struct SG_request_data* entity_info, mode_t* mode, void* cls ) {
  
   int rc = 0;
   struct UG_state* ug = (struct UG_state*)SG_gateway_cls( gateway );
   int64_t block_version = 0;
   UG_handle_t* fi = NULL;
   struct fskit_entry* fent = NULL;
   struct UG_inode* inode = NULL;
   uint64_t file_id = 0;
   int64_t file_version = 0;
   int close_rc = 0;

   fi = UG_open( ug, reqdat->fs_path, O_RDONLY, &rc );
   if( fi == NULL ) {

      SG_error("UG_open('%s') rc = %d\n", reqdat->fs_path, rc );
      return rc;
   }

   fskit_file_handle_rlock( fi->fh );
   
   fent = fskit_file_handle_get_entry( fi->fh );
   if( fent == NULL ) {
      SG_error("BUG: no entry for handle %p\n", fi->fh );
      exit(1);
   }

   fskit_entry_rlock( fent );
   inode = (struct UG_inode*)fskit_entry_get_user_data( fent );
   if( inode == NULL ) {
      SG_error("BUG: no inode for entry %p\n", fent );
      exit(1);
   }

   if( UG_inode_coordinator_id( inode ) != SG_gateway_id( gateway ) ) {

      // not ours 
      SG_error("Not the coordinator of '%s' (it is now %" PRIu64 ")\n", reqdat->fs_path, UG_inode_coordinator_id( inode ) );
      fskit_entry_unlock( fent );
      fskit_file_handle_unlock( fi->fh );

      rc = UG_close( ug, fi );
      if( rc != 0 ) {

         SG_error("UG_close('%s') rc = %d\n", reqdat->fs_path, rc );
      }
      return rc;
   }

   file_id = UG_inode_file_id( inode );
   file_version = UG_inode_file_version( inode );

   if( mode != NULL ) {
      *mode = fskit_entry_get_mode( fent );
   }
   if( entity_info != NULL ) {
      rc = UG_getblockinfo( ug, reqdat->block_id, &block_version, NULL, fi );
   }

   fskit_entry_unlock( fent );
   fskit_file_handle_unlock( fi->fh );
   inode = NULL;

   if( rc != 0 ) {

      SG_error("UG_getblockinfo(%s[%" PRIu64 "]) rc = %d\n", reqdat->fs_path, reqdat->block_id, rc);
      goto UG_impl_stat_block_out;
   }

   rc = SG_request_data_init_block( gateway, reqdat->fs_path, file_id, file_version, reqdat->block_id, block_version, entity_info );
   if( rc != 0 ) {

      SG_error("SG_request_data_init_block rc = %d\n", rc );
      goto UG_impl_stat_block_out;
   }

UG_impl_stat_block_out:

   close_rc = UG_close( ug, fi );
   if( close_rc != 0 ) {

      SG_error("UG_close('%s') rc = %d\n", reqdat->fs_path, close_rc );
   }

   return rc;
}