[Linux-NTFS-cvs] CVS: ntfs-driver-tng/linux/fs/ntfs dir.c,1.14,1.15
Development moved to https://sourceforge.net/projects/ntfs-3g/
Brought to you by:
antona,
cha0smaster
From: Anton A. <an...@us...> - 2001-09-22 12:54:48
|
Changes by: antona Update of /cvsroot/linux-ntfs/ntfs-driver-tng/linux/fs/ntfs In directory usw-pr-cvs1:/tmp/cvs-serv32336/linux/fs/ntfs Modified Files: dir.c Log Message: Started readdir. Index: dir.c =================================================================== RCS file: /cvsroot/linux-ntfs/ntfs-driver-tng/linux/fs/ntfs/dir.c,v retrieving revision 1.14 retrieving revision 1.15 diff -U2 -r1.14 -r1.15 --- dir.c 2001/08/27 18:39:31 1.14 +++ dir.c 2001/09/22 12:54:46 1.15 @@ -44,5 +44,5 @@ * Note, @uname_len does not include the (optional) terminating NULL character. */ -__u64 ntfs_lookup_ino_by_name(struct inode *dir_ino, const uchar_t *uname, +u64 ntfs_lookup_ino_by_name(struct inode *dir_ino, const uchar_t *uname, const int uname_len) { @@ -55,9 +55,9 @@ INDEX_ALLOCATION *ia; char *index_end; - __u64 mref; + u64 mref; attr_search_context ctx; int err, rc; IGNORE_CASE_BOOL ic; - VCN vcn; // TODO: , old_vcn; + VCN vcn, old_vcn; struct address_space *ia_mapping; struct page *page; @@ -205,5 +205,5 @@ PAGE_CACHE_SHIFT); kaddr = (char*)page_address(page); -//fast_descend_into_child_node: +fast_descend_into_child_node: /* Get to the index allocation block. */ ia = (INDEX_ALLOCATION*)(kaddr + ((vcn << vol->cluster_size_bits) & @@ -349,5 +349,5 @@ ntfs_error(sb, __FUNCTION__ "(): Index entry with " "child node found in a leaf node in " - "in directory inode %li. Impossible! " + "directory inode %li. Impossible! " "Corrupt directory or driver bug. You " "should run chkdsk.", dir_ino->i_ino); @@ -356,10 +356,14 @@ } /* Child node present, descend into it. */ - // TODO: old_vcn = vcn; + old_vcn = vcn; vcn = sle64_to_cpup((char*)ie + le16_to_cpu(ie->length) - 8); if (vcn >= 0) { - // TODO: If vcn is in the same page cache page as - // old_vcn we can recycle the mapped page so we just: - // goto fast_descend_into_child_node; + /* If vcn is in the same page cache page as old_vcn we + * recycle the mapped page. */ + if (old_vcn << vol->cluster_size_bits >> + PAGE_CACHE_SHIFT == vcn << + vol->cluster_size_bits >> + PAGE_CACHE_SHIFT) + goto fast_descend_into_child_node; ntfs_unmap_page(page); goto descend_into_child_node; @@ -391,8 +395,63 @@ } +/* VFS calls readdir with BKL held so no possible RACE conditions. */ static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir) { - ntfs_debug("Entering.\n"); - return -EOPNOTSUPP; + s64 ia_pos; + struct inode *vdir = filp->f_dentry->d_inode; + struct ntfs_inode_info *ndir = NTFS_I(vdir); + struct ntfs_sb_info *vol = NTFS_SB(vdir->i_sb); + int rc, err, ir_pos; + + ntfs_debug("Entering for inode 0x%lx, f_pos 0x%Lx.\n", vdir->i_ino, + filp->f_pos); + rc = err = 0; + /* Get the offset into the index allocation attribute (if >= 0). */ + ia_pos = (s64)filp->f_pos - vol->mft_record_size; + /* Are we at end of dir yet? */ + if (ia_pos >= vdir->i_size) + goto done; + /* Emulate . and .. for all directories. */ + if (!filp->f_pos) { + ntfs_debug("Calling filldir for . with len 1, f_pos 0x0, " + "inode 0x%lx, DT_DIR.\n", vdir->i_ino); + rc = filldir(dirent, ".", 1, filp->f_pos, vdir->i_ino, DT_DIR); + if (rc) + goto done; + filp->f_pos++; + } + if (filp->f_pos == 1) { + ntfs_debug("Calling filldir for .. with len 2, f_pos 0x1, " + "inode 0x%lx, DT_DIR.\n", + filp->f_dentry->d_parent->d_inode->i_ino); + rc = filldir(dirent, "..", 2, filp->f_pos, + filp->f_dentry->d_parent->d_inode->i_ino, + DT_DIR); + if (rc) + goto done; + filp->f_pos++; + } + /* + * Get the offset into the index root attribute (compensating for + * faked . and ..). + */ + ir_pos = (s64)filp->f_pos - 2; + /* + * Start by handling the index root, descending into child nodes as we + * go along. Save the current location in a doubly linked list + * organized as a LIFO. When in a child node, again descend into + * sub-child nodes as and when they are found. + */ + /* We are finished. Set f_pos to EOD. */ + filp->f_pos = vdir->i_size + vol->mft_record_size; +done: +#ifdef DEBUG + if (!rc) + ntfs_debug("EOD, f_pos 0x%Lx, returning 0.\n", filp->f_pos); + else + ntfs_debug("filldir returned %i, f_pos 0x%Lx, returning 0.\n", + rc, filp->f_pos); +#endif + return 0; } @@ -423,5 +482,4 @@ loff_t (*llseek) (struct file *, loff_t, int); ssize_t (*write) (struct file *, const char *, size_t, loff_t *); - int (*readdir) (struct file *, void *, filldir_t); unsigned int (*poll) (struct file *, struct poll_table_struct *); int (*ioctl) (struct inode *, struct file *, unsigned int, |