Changes by: antona
Update of /cvsroot/linux-ntfs/linux-ntfs/include
In directory usw-pr-cvs1:/tmp/cvs-serv1807
Modified Files:
bitmap.h mft.h volume.h
Log Message:
We now have files and keep track of them on a per volume basis and same
for inodes (mft_records). At least conceptually anyway.
Index: bitmap.h
===================================================================
RCS file: /cvsroot/linux-ntfs/linux-ntfs/include/bitmap.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -U2 -r1.2 -r1.3
--- bitmap.h 2001/01/25 22:25:43 1.2
+++ bitmap.h 2001/04/03 22:41:30 1.3
@@ -36,5 +36,5 @@
/**
- * set_bit - set a bit in a field of bits
+ * ntfs_set_bit - set a bit in a field of bits
* @bitmap: field of bits
* @bit: bit to set
@@ -43,5 +43,5 @@
* Set the bit @bit in the @bitmap to @new_value. Ignore all errors.
*/
-extern inline void set_bit(__u8 *bitmap, const __u64 bit,
+extern inline void ntfs_set_bit(__u8 *bitmap, const __u64 bit,
const __u8 new_value);
@@ -54,5 +54,5 @@
* Return -1 on error.
*/
-extern inline char get_bit(const __u8 *bitmap, const __u64 bit);
+extern inline char ntfs_get_bit(const __u8 *bitmap, const __u64 bit);
/**
@@ -65,5 +65,5 @@
* Return -1 on error.
*/
-extern inline char get_and_set_bit(__u8 *bitmap, const __u64 bit,
+extern inline char ntfs_get_and_set_bit(__u8 *bitmap, const __u64 bit,
const __u8 new_value);
Index: mft.h
===================================================================
RCS file: /cvsroot/linux-ntfs/linux-ntfs/include/mft.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -U2 -r1.11 -r1.12
--- mft.h 2001/04/02 02:04:37 1.11
+++ mft.h 2001/04/03 22:41:30 1.12
@@ -23,4 +23,8 @@
#define MFT_H
+#include <asm/atomic.h>
+#include <asm/semaphore.h>
+#include <linux/list.h>
+
#include "endians.h"
#include "ntfs_rec.h"
@@ -231,4 +235,207 @@
*/
inline __u32 get_mft_record_data_size(const MFT_RECORD *b);
+
+/*
+ * Implementation of files (aka mft records, aka inodes) in memory.
+ * ================================================================
+ *
+ * NOTE: I have completely ignored the existence of things like directories
+ * and directory references for the moment! These will just be added later on.
+ * The directories themselves are of course covered by being base mft records
+ * and hence follow the same semantics like every other mft record.
+ *
+ * Volume struct (typedef is in volume.h).
+ * ---------------------------------------
+ *
+ * open_files: Linked list of ntfs_file struct pointers, keeping track
+ * of all files which have been loaded into memory and are
+ * open.
+ *
+ * nr_open_files: Number of open files.
+ *
+ * closed_files: Linked list of ntfs_file struct pointers, keeping track
+ * of all cached files which are not open any more.
+ *
+ * nr_closed_files: Number of closed files.
+ *
+ * max_files: Maximum number of nr_open_files + nr_closed_files.
+ *
+ * files_sem: Read write semaphore to serialize access to the above
+ * structure members (open_files, nr_open_files,
+ * closed_files, nr_closed_files and max_files).
+ *
+ * As files are opened/closed, records move from one list to the other. When a
+ * file is opened it moves to the front of files_open as we expect to do I/O on
+ * it very soon so want quick access to it. When a file is closed, it moves to
+ * the end of files_closed as we don't expect it to be opened any time soon.
+ *
+ * Note: We probably want to replace these with hash tables once the library
+ * matures and users start complaining about the speed of it... but this will
+ * do for now.
+ *
+ * mft_entries: Linked list of all loaded mft records (disk inodes) in
+ * order of ascending mft record number (disk inode number,
+ * i.e. disregarding the sequence number). Note, the list
+ * members are not the actual MFT_RECORDS, but in memory
+ * mft_entry structs.
+ *
+ * nr_mft_entries: Number of mft_entries.
+ *
+ * dirty_mft_entries: Linked list of all loaded mft records which are dirty.
+ * Used by the disk writter thread. When a mft_entry is
+ * marked dirty, the entry is added to the end of this
+ * list. When it is flushed to disk, it is marked clean
+ * and removed from this list.
+ *
+ * nr_dirty_mft_entries: Number of dirty mft_entries.
+ *
+ * mft_entries_sem: Read write semaphore to serialize access to the above
+ * structure members (mft_entries, nr_mft_entries and their
+ * dirty equivalents).
+ *
+ * The mft_entry struct.
+ * ---------------------
+ *
+ * Each loaded mft record is represented by the mft_entry structure which
+ * contains these members:
+ *
+ * m_rec: Pointer to the actual MFT_RECORD. (Only valid if mapped flag is
+ * set.)
+ *
+ * m_rec_sem: Read write semaphore controlling access to m_rec. Only one
+ * writer at a time (and no readers while one writer) as the mft
+ * record will be corrupt during the write process.
+ *
+ * m_flags: Atomic flags describing the mft entry / record:
+ *
+ * mapped: Is the MFT_RECORD actually in memory? (Is mrec valid?)
+ *
+ * dirty: Does the record need to be written to disk? (If not, it
+ * is safe to discard m_rec, but only if m_count is zero
+ * and we are holding m_rec_sem for writing.)
+ *
+ * m_ref: Mft reference of the mft record described by this entry. (This
+ * includes the sequence number for consistency checking purposes.)
+ *
+ * m_count: Atomic usage count. When zero this record is not referenced by
+ * any files and can be thrown away safely (writing it to disk
+ * first if dirty flag is set).
+ *
+ * m_list: Hook for the mft_entries linked list.
+ *
+ * m_vol: Volume this entry and its mft record belong to.
+ *
+ * Future:
+ *
+ * Add aging for mft_entries.
+ *
+ * The ntfs_file struct (file = base mft record).
+ * ----------------------------------------------
+ *
+ * Each loaded file is described by an ntfs_file struct, which contains these
+ * members:
+ *
+ * f_mft_refs: The mft references of the file (i.e. the on disk inode number).
+ * This is an array of MFT_REFERENCEs. The first reference is the
+ * base mft record and if any others exist they are the associated
+ * loaded extension mft records. Used for attribute list purposes.
+ *
+ * f_mft_entries: The loaded mft records for the file. This is an array of
+ * pointers to mft_entries, corresponding to the f_mft_refs. This
+ * is not strictly necessary but results in a big speed up as we
+ * don't need to search the vol->mft_entries list every time...
+ *
+ * When an entry is referenced in the above lists the usage count for the
+ * corresponding entry is increased by one.
+ *
+ * f_nr_mft_refs: Number of records in the f_mft_* arrays. If > 1, we
+ * know there must be an attribute list attribute (but if 1, we
+ * cannot assume there isn't one). This is of course the same as
+ * a possible f_nr_mft_entries, but refs is shorter to write. (-;
+ *
+ * f_sem: Read write semaphore for serializing access to the above struct
+ * members (f_mft_refs, f_mft_entries and f_nr_mft_refs).
+ *
+ * f_count: Atomic usage count. When zero this file is not open by anyone
+ * and can be thrown away safely. No need to concern oneself with
+ * dirty state as this is done on a mft_entry level, i.e. one level
+ * below the idea of files.
+ *
+ * f_list: Hook into vol->open/closed_files list.
+ *
+ * Notes:
+ *
+ * - No field to know whether we have the file open for writing as this is
+ * provided on a mft_entry level, i.e. below the files/directories level.
+ * This might turn out to be a mistake and is subject to change in the
+ * future if the current approach turns out not to work...
+ */
+
+/* Mft entry flag bit values */
+#define ME_mapped 0
+#define ME_dirty 1
+ /* bits 2-31 reserved for future use */
+
+#define MftEntryMapped(me) test_bit(ME_mapped, &(me)->m_flags)
+#define SetMftEntryMapped(me) set_bit(ME_mapped, &(me)->m_flags)
+#define ClearMftEntryMapped(me) clear_bit(ME_mapped, &(me)->m_flags)
+
+#define MftEntryDirty(me) test_bit(ME_dirty, &(me)->m_flags)
+#define SetMftEntryDirty(me) set_bit(ME_dirty, &(me)->m_flags)
+#define ClearMftEntryDirty(me) clear_bit(ME_dirty, &(me)->m_flags)
+
+extern void __set_mft_entry_dirty(mft_entry *);
+
+static inline void set_mft_entry_dirty(mft_entry *me)
+{
+ if (!test_and_set_bit(ME_dirty, &me->m_flags))
+ __set_mft_entry_dirty(me);
+}
+
+typedef struct {
+ MFT_RECORD *m_rec;
+ rw_semaphore m_rec_sem;
+ unsigned int m_flags; /* mapped, dirty */
+ MFT_REFERENCE m_ref;
+ atomic_t m_count;
+ struct list_head m_list;
+ ntfs_volume *m_vol;
+} mft_entry;
+
+typedef struct {
+ MFT_REFERENCE *f_mft_refs;
+ mft_erntry *f_mft_entries;
+ int f_nr_mft_refs;
+ rw_semaphore f_sem;
+ atomic_t f_count;
+ struct list_head f_list;
+} ntfs_file;
+
+/**
+ * ntfs_open_by_mref - open an ntfs file, i.e. mft record, given a mft reference
+ * @vol: ntfs volume to operate on
+ * @mref: mft_reference of base mft record to open
+ *
+ * Open an ntfs_file (using file to mean any base mft record) given the mft
+ * reference of the mft record (i.e. the inode number). To do this allocate an
+ * ntfs_file structure (adding it to the vol->open_files array), or if the file
+ * is already loaded, just find it in the vol->open_/closed_files arrays.
+ *
+ * Return a pointer to the ntfs_file structure in the vol->open_files array.
+ * This pointer should be treated completely opaquely by the user! Never
+ * use it for anything except as a parameter to functions taking a ntfs_file
+ * pointer as a parameter.
+ */
+ntfs_file *ntfs_open_by_mref(const ntfs_volume *vol, const MFT_REFERENCE *mref);
+
+/**
+ * ntfs_close - close an ntfs_file
+ * @vol: ntfs volume to operate on
+ * @fref: ntfs_file pointer to close
+ *
+ * Close a previously opened ntfs file. Return zero on success or -ERRNO on
+ * error, where ERRNO is the error number.
+ */
+int ntfs_close(ntfs_file *fref);
#endif /* defined MFT_H */
Index: volume.h
===================================================================
RCS file: /cvsroot/linux-ntfs/linux-ntfs/include/volume.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -U2 -r1.5 -r1.6
--- volume.h 2001/04/02 02:04:37 1.5
+++ volume.h 2001/04/03 22:41:30 1.6
@@ -24,4 +24,7 @@
#include <stdio.h>
+#include <asm/atomic.h>
+#include <asm/semaphore.h>
+#include <linux/list.h>
#include "attrib.h"
@@ -81,5 +84,5 @@
same interpretation as the lcn_bitmap above
but except that it keeps track of the usage
- of the mft recoreds rather than the lcns. */
+ of the mft records rather than the lcns. */
run_list mft_runlist; /* Decompressed run list of the data attribute
of FILE_$Mft. */
@@ -97,5 +100,31 @@
or 0 if a mft record is smaller than
a cluster. */
-
+ struct list_head open_files; /* Linked list of ntfs_file struct
+ pointers, keeping track of all files
+ which have been loaded into memory
+ and are open. */
+ int nr_open_files; /* Number of open files. */
+ struct list_head closed_files; /* Linked list of ntfs_file struct
+ pointers, keeping track of all cached
+ files which are not open any more. */ int nr_closed_files; /* Number of closed files. */
+ int max_files; /* Maximum number of nr_open_files + nr_ closed_files. */
+ rw_semaphore files_sem; /* Read write semaphore to serialize
+ access to open_files, nr_open_files,
+ closed_files, nr_closed_files and
+ max_files). */
+ struct list_head mft_entries; /* Linked list of all loaded mft records
+ (disk inodes) in order of ascending
+ mft record number (disk inode number,
+ disregarding the sequence number).
+ Note, the list members are mft_entry
+ struct pointers. */
+ int nr_mft_entries; /* Number of mft_entries. */
+ struct list_head dirty_mft_entries; /* Linked list of all loaded mft
+ records which are dirty. */
+ int nr_dirty_mft_entries; /* Number of dirty mft_entries. */
+ rw_semaphore mft_entries_sem; /* Read write semaphore to serialize
+ access to mft_entries,
+ nr_mft_entries and their dirty
+ equivalents. */
} ntfs_volume;
|