Changeset 606 for trunk/kernel/mm/ppm.c


Ignore:
Timestamp:
Dec 3, 2018, 12:20:18 PM (5 years ago)
Author:
alain
Message:

Improve the FAT32 file system to support cat, rm, cp commands.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/kernel/mm/ppm.c

    r585 r606  
    3939#include <mapper.h>
    4040#include <ppm.h>
     41#include <vfs.h>
    4142
    4243////////////////////////////////////////////////////////////////////////////////////////
     
    395396//////////////////////////////////////////////////////////////////////////////////////
    396397
    397 /////////////////////////////////////////
    398 bool_t ppm_page_do_dirty( page_t * page )
     398//////////////////////////////////////////
     399bool_t ppm_page_do_dirty( xptr_t page_xp )
    399400{
    400401        bool_t done = false;
    401402
     403    // get page cluster and local pointer
     404    page_t * page_ptr = GET_PTR( page_xp );
     405    cxy_t    page_cxy = GET_CXY( page_xp );
     406
     407    // get local pointer on PPM (same in all clusters)
    402408        ppm_t * ppm = &LOCAL_CLUSTER->ppm;
    403409
    404         // lock the PPM dirty_list
    405         queuelock_acquire( &ppm->dirty_lock );
    406 
    407         if( !page_is_flag( page , PG_DIRTY ) )
     410    // build extended pointers on page lock, page flags, and PPM dirty list lock
     411    xptr_t page_lock_xp  = XPTR( page_cxy , &page_ptr->lock  );   
     412    xptr_t page_flags_xp = XPTR( page_cxy , &page_ptr->flags );
     413    xptr_t dirty_lock_xp = XPTR( page_cxy , &ppm->dirty_lock );
     414           
     415        // lock the remote PPM dirty_list
     416        remote_queuelock_acquire( dirty_lock_xp );
     417
     418    // lock the remote page
     419    remote_busylock_acquire( page_lock_xp );
     420
     421    // get remote page flags
     422    uint32_t flags = hal_remote_l32( page_flags_xp );
     423
     424        if( (flags & PG_DIRTY) == 0 )
    408425        {
    409426                // set dirty flag in page descriptor
    410                 page_set_flag( page , PG_DIRTY );
    411 
    412                 // register page in PPM dirty list
    413                 list_add_first( &ppm->dirty_root , &page->list );
     427        hal_remote_s32( page_flags_xp , flags | PG_DIRTY );
     428
     429                // The PPM dirty list is a LOCAL list !!!
     430        // We must update 4 pointers to insert a new page in this list.
     431        // We can use the standard LIST API when the page is local,
     432        // but we cannot use the standard API if the page is remote...
     433
     434        if( page_cxy == local_cxy )         // locally update the PPM dirty list
     435        {
     436            list_add_first( &ppm->dirty_root , &page_ptr->list );
     437        }
     438        else                                // remotely update the PPM dirty list
     439        {
     440            // get local and remote pointers on "root" list entry
     441            list_entry_t * root    = &ppm->dirty_root;
     442            xptr_t         root_xp = XPTR( page_cxy , root );
     443
     444            // get local and remote pointers on "page" list entry
     445            list_entry_t * list    = &page_ptr->list;
     446            xptr_t         list_xp = XPTR( page_cxy , list );
     447
     448            // get local and remote pointers on first dirty page
     449            list_entry_t * dirt    = hal_remote_lpt( XPTR( page_cxy, &root->next ) );
     450            xptr_t         dirt_xp = XPTR( page_cxy , dirt );
     451
     452            // set root.next, list.next, list pred, curr.pred in remote cluster
     453            hal_remote_spt( root_xp                    , list );
     454            hal_remote_spt( list_xp                    , dirt );
     455            hal_remote_spt( list_xp + sizeof(intptr_t) , root );
     456            hal_remote_spt( dirt_xp + sizeof(intptr_t) , list );
     457        }
     458
    414459                done = true;
    415460        }
    416461
    417         // unlock the PPM dirty_list
    418         queuelock_release( &ppm->dirty_lock );
     462    // unlock the remote page
     463    remote_busylock_release( page_lock_xp );
     464
     465        // unlock the remote PPM dirty_list
     466        remote_queuelock_release( dirty_lock_xp );
    419467
    420468        return done;
    421 }
    422 
    423 ///////////////////////////////////////////
    424 bool_t ppm_page_undo_dirty( page_t * page )
     469
     470} // end ppm_page_do_dirty()
     471
     472////////////////////////////////////////////
     473bool_t ppm_page_undo_dirty( xptr_t page_xp )
    425474{
    426475        bool_t done = false;
    427476
     477    // get page cluster and local pointer
     478    page_t * page_ptr = GET_PTR( page_xp );
     479    cxy_t    page_cxy = GET_CXY( page_xp );
     480
     481    // get local pointer on PPM (same in all clusters)
    428482        ppm_t * ppm = &LOCAL_CLUSTER->ppm;
    429483
    430         // lock the dirty_list
    431         queuelock_acquire( &ppm->dirty_lock );
    432 
    433         if( page_is_flag( page , PG_DIRTY) )
    434         {
    435                 // clear dirty flag in page descriptor
    436                 page_clear_flag( page , PG_DIRTY );
    437 
    438                 // remove page from PPM dirty list
    439                 list_unlink( &page->list );
     484    // build extended pointers on page lock, page flags, and PPM dirty list lock
     485    xptr_t page_lock_xp  = XPTR( page_cxy , &page_ptr->lock  );
     486    xptr_t page_flags_xp = XPTR( page_cxy , &page_ptr->flags );
     487    xptr_t dirty_lock_xp = XPTR( page_cxy , &ppm->dirty_lock );
     488           
     489        // lock the remote PPM dirty_list
     490        remote_queuelock_acquire( XPTR( page_cxy , &ppm->dirty_lock ) );
     491
     492    // lock the remote page
     493    remote_busylock_acquire( page_lock_xp );
     494
     495    // get remote page flags
     496    uint32_t flags = hal_remote_l32( page_flags_xp );
     497
     498        if( (flags & PG_DIRTY) )  // page is dirty
     499        {
     500                // reset dirty flag in page descriptor
     501        hal_remote_s32( page_flags_xp , flags & (~PG_DIRTY) );
     502
     503                // The PPM dirty list is a LOCAL list !!!
     504        // We must update 4 pointers to remove a page from this list.
     505        // we can use the standard LIST API when the page is local,
     506        // but we cannot use the standard API if the page is remote...
     507
     508        if( page_cxy == local_cxy )         // locally update the PPM dirty list
     509        {
     510            list_unlink( &page_ptr->list );
     511        }
     512        else                                // remotely update the PPM dirty list
     513        {
     514            // get local and remote pointers on "page" list entry
     515            list_entry_t * list    = &page_ptr->list;
     516            xptr_t         list_xp = XPTR( page_cxy , list );
     517
     518            // get local and remote pointers on "next" page list entry
     519            list_entry_t * next    = hal_remote_lpt( list_xp );
     520            xptr_t         next_xp = XPTR( page_cxy , next );
     521
     522            // get local and remote pointers on "pred" page list entry
     523            list_entry_t * pred    = hal_remote_lpt( list_xp + sizeof(intptr_t) );
     524            xptr_t         pred_xp = XPTR( page_cxy , pred );
     525
     526            // set root.next, list.next, list pred, curr.pred in remote cluster
     527            hal_remote_spt( pred_xp                    , next );
     528            hal_remote_spt( list_xp                    , NULL );
     529            hal_remote_spt( list_xp + sizeof(intptr_t) , NULL );
     530            hal_remote_spt( next_xp + sizeof(intptr_t) , pred );
     531        }
     532
    440533                done = true;
    441534        }
    442535
    443         // unlock the dirty_list
    444         queuelock_release( &ppm->dirty_lock );
     536    // unlock the remote page
     537    remote_busylock_release( page_lock_xp );
     538
     539        // unlock the remote PPM dirty_list
     540        remote_queuelock_release( dirty_lock_xp );
    445541
    446542        return done;
    447 }
    448 
    449 ///////////////////////////////
    450 void ppm_sync_all_pages( void )
    451 {
    452         page_t   * page;
    453         ppm_t    * ppm = &LOCAL_CLUSTER->ppm;
     543
     544}  // end ppm_page_undo_dirty()
     545
     546/////////////////////////////////
     547void ppm_sync_dirty_pages( void )
     548{
     549        ppm_t * ppm = &LOCAL_CLUSTER->ppm;
     550
     551    // get local pointer on PPM dirty_root
     552    list_entry_t * dirty_root = &ppm->dirty_root;
     553
     554    // build extended pointer on PPM dirty_lock
     555    xptr_t dirty_lock_xp = XPTR( local_cxy , &ppm->dirty_lock );
    454556
    455557        // get the PPM dirty_list lock
    456         queuelock_acquire( &ppm->dirty_lock );
     558        remote_queuelock_acquire( dirty_lock_xp );
    457559
    458560        while( !list_is_empty( &ppm->dirty_root ) )
    459561        {
    460                 page = LIST_FIRST( &ppm->dirty_root ,  page_t , list );
     562                page_t * page = LIST_FIRST( dirty_root ,  page_t , list );
     563        xptr_t   page_xp = XPTR( local_cxy , page );
     564
     565        // build extended pointer on page lock
     566        xptr_t page_lock_xp = XPTR( local_cxy , &page->lock );
    461567
    462568                // get the page lock
    463                 remote_busylock_acquire( XPTR( local_cxy, &page->lock ) );
     569                remote_busylock_acquire( page_lock_xp );
    464570
    465571                // sync the page
    466                 vfs_mapper_move_page( page , false );  // from mapper
     572                vfs_fs_move_page( page_xp , false );  // from mapper to device
    467573
    468574                // release the page lock
    469                 remote_busylock_release( XPTR( local_cxy , &page->lock ) );
     575                remote_busylock_release( page_lock_xp );
    470576        }
    471577
    472578        // release the PPM dirty_list lock
    473         queuelock_release( &ppm->dirty_lock );
    474 }
    475 
     579        remote_queuelock_release( dirty_lock_xp );
     580
     581}  // end ppm_sync_dirty_pages()
     582
Note: See TracChangeset for help on using the changeset viewer.