Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
Functions
mft.h File Reference
#include <linux/fs.h>
#include <linux/highmem.h>
#include <linux/pagemap.h>
#include "inode.h"

Go to the source code of this file.

Functions

MFT_RECORD * map_mft_record (ntfs_inode *ni)
 
void unmap_mft_record (ntfs_inode *ni)
 
MFT_RECORD * map_extent_mft_record (ntfs_inode *base_ni, MFT_REF mref, ntfs_inode **ntfs_ino)
 

Function Documentation

MFT_RECORD* map_extent_mft_record ( ntfs_inode base_ni,
MFT_REF  mref,
ntfs_inode **  ntfs_ino 
)

map_extent_mft_record - load an extent inode and attach it to its base : base ntfs inode : mft reference of the extent inode to load : on successful return, pointer to the ntfs_inode structure

Load the extent mft record and attach it to its base inode . Return the mapped extent mft record if IS_ERR(result) is false. Otherwise PTR_ERR(result) gives the negative error code.

On successful return, contains a pointer to the ntfs_inode structure of the mapped extent inode.

Definition at line 246 of file mft.c.

MFT_RECORD* map_mft_record ( ntfs_inode ni)

map_mft_record - map, pin and lock an mft record : ntfs inode whose MFT record to map

First, take the mrec_lock mutex. We might now be sleeping, while waiting for the mutex if it was already locked by someone else.

The page of the record is mapped using map_mft_record_page() before being returned to the caller.

This in turn uses ntfs_map_page() to get the page containing the wanted mft record (it in turn calls read_cache_page() which reads it in from disk if necessary, increments the use count on the page so that it cannot disappear under us and returns a reference to the page cache page).

If read_cache_page() invokes ntfs_readpage() to load the page from disk, it sets PG_locked and clears PG_uptodate on the page. Once I/O has completed and the post-read mst fixups on each mft record in the page have been performed, the page gets PG_uptodate set and PG_locked cleared (this is done in our asynchronous I/O completion handler end_buffer_read_mft_async()). ntfs_map_page() waits for PG_locked to become clear and checks if PG_uptodate is set and returns an error code if not. This provides sufficient protection against races when reading/using the page.

However there is the write mapping to think about. Doing the above described checking here will be fine, because when initiating the write we will set PG_locked and clear PG_uptodate making sure nobody is touching the page contents. Doing the locking this way means that the commit to disk code in the page cache code paths is automatically sufficiently locked with us as we will not touch a page that has been locked or is not uptodate. The only locking problem then is them locking the page while we are accessing it.

So that code will end up having to own the mrec_lock of all mft records/inodes present in the page before I/O can proceed. In that case we wouldn't need to bother with PG_locked and PG_uptodate as nobody will be accessing anything without owning the mrec_lock mutex. But we do need to use them because of the read_cache_page() invocation and the code becomes so much simpler this way that it is well worth it.

The mft record is now ours and we return a pointer to it. You need to check the returned pointer with IS_ERR() and if that is true, PTR_ERR() will return the error code.

NOTE: Caller is responsible for setting the mft record dirty before calling unmap_mft_record(). This is obviously only necessary if the caller really modified the mft record... Q: Do we want to recycle one of the VFS inode state bits instead? A: No, the inode ones mean we want to change the mft record, not we want to write it out.

Definition at line 155 of file mft.c.

void unmap_mft_record ( ntfs_inode ni)

unmap_mft_record - release a mapped mft record : ntfs inode whose MFT record to unmap

We release the page mapping and the mrec_lock mutex which unmaps the mft record and releases it for others to get hold of. We also release the ntfs inode by decrementing the ntfs inode reference count.

NOTE: If caller has modified the mft record, it is imperative to set the mft record dirty BEFORE calling unmap_mft_record().

Definition at line 213 of file mft.c.