Commit ca2faf4b authored by Anton Altaparmakov's avatar Anton Altaparmakov Committed by Anton Altaparmakov

NTFS: Repeat some changes from tng-0.0.8 which somehow got lost on the way

from the CVS import into BitKeeper. In particular, use parent_ino() and
change run_list lock to read/write semaphore instead of a read/write
spin lock since we need to be able to sleep.
parent 00f25ce0
......@@ -30,14 +30,17 @@ ToDo:
locked or RACE. load_attribute_list() which we call without any locks
held already performs such an optimization but that is no longer
possible when using the spinlock on the run lists as this would sleep
in between. Either need different type of optimization as above or
need to change the read/write spinlock to a read/write semaphore.
in between. But now we have a semaphore so are ok. Update
load_attribute_list to use the semaphore so can be called outside
read_inode, too. Apply the same optimization where desired.
tng-0.0.9 - Work in progress
- Add kill_super, just keeping up with the vfs changes in the kernel.
- Repeat some changes from tng-0.0.8 that somehow got lost on the way
from the CVS import into BitKeeper.
tng-0.0.8 - 08/03/2002 - BitKeeper ChangeSet 1.386
tng-0.0.8 - 08/03/2002 - Now using BitKeeper, http://linux-ntfs.bkbits.net/
- Replace bdevname(sb->s_dev) with sb->s_id.
- Remove now superfluous new-line characters in all callers of
......@@ -100,11 +103,13 @@ tng-0.0.8 - 08/03/2002 - BitKeeper ChangeSet 1.386
which is then referenced but not copied.
- Rename run_list structure to run_list_element and create a new
run_list structure containing a pointer to a run_list_element
structure and a read/write spinlock. Adapt all usesrs of run lists
structure and a read/write semaphore. Adapt all users of run lists
to new scheme and take and release the lock as needed. This fixes a
nasty race as the run_list changes even when inodes are locked for
reading and even when the inode isn't locked at all, so we really
needed the serialization.
needed the serialization. We use a semaphore rather than a spinlock
as memory allocations can sleep and doing everything GFP_ATOMIC
would be silly.
- Cleanup read_inode() removing all code checking for lowest_vcn != 0.
This can never happen due to the nature of lookup_attr() and how we
support attribute lists. If it did happen it would imply the inode
......@@ -112,6 +117,7 @@ tng-0.0.8 - 08/03/2002 - BitKeeper ChangeSet 1.386
- Check for lowest_vcn != 0 in ntfs_read_inode() and mark the inode as
bad if found.
- Update to 2.5.6-pre2 changes in struct address_space.
- Use parent_ino() when accessing d_parent inode number in dir.c.
- Import Sourceforge CVS repository into BitKeeper repository:
http://linux-ntfs.bkbits.net/ntfs-tng-2.5
- Update fs/Makefile, fs/Config.help, fs/Config.in, and
......
......@@ -100,9 +100,9 @@ int ntfs_file_get_block(struct inode *vi, const sector_t blk,
retry_remap:
/* Convert the vcn to the corresponding logical cluster number (lcn). */
read_lock(&ni->run_list.lock);
down_read(&ni->run_list.lock);
lcn = vcn_to_lcn(ni->run_list.rl, vcn);
read_unlock(&ni->run_list.lock);
up_read(&ni->run_list.lock);
/* Successful remap. */
if (lcn >= 0) {
/* Setup the buffer head to describe the correct block. */
......@@ -297,9 +297,9 @@ static int ntfs_mftbmp_get_block(ntfs_volume *vol, const sector_t blk,
ntfs_debug("Done.");
return 0;
}
read_lock(&vol->mftbmp_rl.lock);
down_read(&vol->mftbmp_rl.lock);
lcn = vcn_to_lcn(vol->mftbmp_rl.rl, vcn);
read_unlock(&vol->mftbmp_rl.lock);
up_read(&vol->mftbmp_rl.lock);
ntfs_debug("lcn = 0x%Lx.", (long long)lcn);
if (lcn < 0LL) {
ntfs_error(vol->sb, "Returning -EIO, lcn = 0x%Lx.",
......
......@@ -831,7 +831,7 @@ int map_run_list(ntfs_inode *ni, VCN vcn)
}
/* Lock the run list. */
write_lock(&ni->run_list.lock);
down_write(&ni->run_list.lock);
/* Make sure someone else didn't do the work while we were spinning. */
if (likely(vcn_to_lcn(ni->run_list.rl, vcn) <= LCN_RL_NOT_MAPPED)) {
......@@ -849,7 +849,7 @@ int map_run_list(ntfs_inode *ni, VCN vcn)
}
/* Unlock the run list. */
write_unlock(&ni->run_list.lock);
up_write(&ni->run_list.lock);
put_attr_search_ctx(ctx);
......
......@@ -30,6 +30,12 @@
#include "types.h"
#include "layout.h"
static inline void init_run_list(run_list *rl)
{
rl->rl = NULL;
init_rwsem(&rl->lock);
}
typedef enum {
LCN_HOLE = -1, /* Keep this as highest value or die! */
LCN_RL_NOT_MAPPED = -2,
......
......@@ -569,9 +569,9 @@ int ntfs_file_read_compressed_block(struct page *page)
// TODO: AIA
}
/* Find lcn of vcn and convert it into blocks. */
read_lock(&ni->run_list.lock);
down_read(&ni->run_list.lock);
lcn = vcn_to_lcn(ni->run_list.rl, vcn);
read_unlock(&ni->run_list.lock);
up_read(&ni->run_list.lock);
ntfs_debug("Reading vcn = 0x%Lx, lcn = 0x%Lx.",
(long long)vcn, (long long)lcn);
if (lcn < 0) {
......
......@@ -539,12 +539,10 @@ static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
}
if (filp->f_pos == 1) {
ntfs_debug("Calling filldir for .. with len 2, f_pos 0x1, "
"inode 0x%Lx, DT_DIR.",
(unsigned long long)NTFS_I(
filp->f_dentry->d_parent->d_inode)->mft_no);
"inode 0x%lx, DT_DIR.",
parent_ino(filp->f_dentry));
rc = filldir(dirent, "..", 2, filp->f_pos,
filp->f_dentry->d_parent->d_inode->i_ino,
DT_DIR);
parent_ino(filp->f_dentry), DT_DIR);
if (rc)
goto done;
filp->f_pos++;
......
......@@ -77,13 +77,13 @@ static void __ntfs_init_inode(struct super_block *sb, ntfs_inode *ni)
memset(ni, 0, sizeof(ntfs_inode));
atomic_set(&ni->count, 1);
ni->vol = NULL;
INIT_RUN_LIST(&ni->run_list);
init_run_list(&ni->run_list);
init_rwsem(&ni->mrec_lock);
atomic_set(&ni->mft_count, 0);
ni->page = NULL;
ni->attr_list = NULL;
INIT_RUN_LIST(&ni->attr_list_rl);
INIT_RUN_LIST(&ni->_IDM(bmp_rl));
init_run_list(&ni->attr_list_rl);
init_run_list(&ni->_IDM(bmp_rl));
init_MUTEX(&ni->extent_lock);
ni->_INE(base_ntfs_ino) = NULL;
ni->vol = NTFS_SB(sb);
......@@ -1304,17 +1304,17 @@ void __ntfs_clear_inode(ntfs_inode *ni)
kfree(ni->_INE(extent_ntfs_inos));
}
/* Free all alocated memory. */
write_lock(&ni->run_list.lock);
down_write(&ni->run_list.lock);
ntfs_free(ni->run_list.rl);
ni->run_list.rl = NULL;
write_unlock(&ni->run_list.lock);
up_write(&ni->run_list.lock);
ntfs_free(ni->attr_list);
write_lock(&ni->attr_list_rl.lock);
down_write(&ni->attr_list_rl.lock);
ntfs_free(ni->attr_list_rl.rl);
ni->attr_list_rl.rl = NULL;
write_unlock(&ni->attr_list_rl.lock);
up_write(&ni->attr_list_rl.lock);
}
void ntfs_clear_inode(ntfs_inode *ni)
......@@ -1342,9 +1342,9 @@ void ntfs_clear_big_inode(struct inode *vi)
__ntfs_clear_inode(ni);
if (S_ISDIR(vi->i_mode)) {
write_lock(&ni->_IDM(bmp_rl).lock);
down_write(&ni->_IDM(bmp_rl).lock);
ntfs_free(ni->_IDM(bmp_rl).rl);
write_unlock(&ni->_IDM(bmp_rl).lock);
up_write(&ni->_IDM(bmp_rl).lock);
}
return;
}
......
......@@ -205,9 +205,9 @@ static int ntfs_mft_readpage(struct file *file, struct page *page)
vcn_ofs = ((VCN)iblock << blocksize_bits) &
vol->cluster_size_mask;
/* Convert the vcn to the corresponding lcn. */
read_lock(&ni->run_list.lock);
down_read(&ni->run_list.lock);
lcn = vcn_to_lcn(ni->run_list.rl, vcn);
read_unlock(&ni->run_list.lock);
up_read(&ni->run_list.lock);
if (lcn >= 0) {
/* Setup buffer head to correct block. */
bh->b_dev = vi->i_dev;
......
......@@ -1130,10 +1130,10 @@ void ntfs_put_super(struct super_block *vfs_sb)
vol->mftbmp_mapping.a_ops = NULL;
vol->mftbmp_mapping.host = NULL;
up_write(&vol->mftbmp_lock);
write_lock(&vol->mftbmp_rl.lock);
down_write(&vol->mftbmp_rl.lock);
ntfs_free(vol->mftbmp_rl.rl);
vol->mftbmp_rl.rl = NULL;
write_unlock(&vol->mftbmp_rl.lock);
up_write(&vol->mftbmp_rl.lock);
vol->upcase_len = 0;
/*
* Decrease the number of mounts and destroy the global default upcase
......@@ -1507,7 +1507,7 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent)
INIT_LIST_HEAD(&vol->mftbmp_mapping.i_mmap_shared);
#endif
spin_lock_init(&vol->mftbmp_mapping.i_shared_lock);
INIT_RUN_LIST(&vol->mftbmp_rl);
init_run_list(&vol->mftbmp_rl);
vol->mftmirr_ino = NULL;
vol->lcnbmp_ino = NULL;
init_rwsem(&vol->lcnbmp_lock);
......
......@@ -67,19 +67,9 @@ typedef struct { /* In memory vcn to lcn mapping structure element. */
*/
typedef struct {
run_list_element *rl;
rwlock_t lock;
struct rw_semaphore lock;
} run_list;
#define RUN_LIST_INIT { NULL, RW_LOCK_UNLOCKED }
#define RUN_LIST(name) run_list name = RUN_LIST_INIT
#define INIT_RUN_LIST(runlist) do { \
run_list *___rl = runlist; \
___rl->rl = NULL; \
___rl->lock = RW_LOCK_UNLOCKED; \
} while (0)
typedef enum {
FALSE = 0,
TRUE = 1
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment