Commit de8ea577 authored by Anton Altaparmakov's avatar Anton Altaparmakov

NTFS: Get rid of the ugly transparent union in fs/ntfs/dir.c::ntfs_readdir()

      and ntfs_filldir() as per suggestion from Al Viro.
Signed-off-by: default avatarAnton Altaparmakov <aia21@cantab.net>
parent 60bec29c
...@@ -28,6 +28,8 @@ ToDo/Notes: ...@@ -28,6 +28,8 @@ ToDo/Notes:
ACLs yet. ACLs yet.
- Remove BKL use from ntfs_setattr() syncing up with the rest of the - Remove BKL use from ntfs_setattr() syncing up with the rest of the
kernel. kernel.
- Get rid of the ugly transparent union in fs/ntfs/dir.c::ntfs_readdir()
and ntfs_filldir() as per suggestion from Al Viro.
2.1.18 - Fix scheduling latencies at mount time as well as an endianness bug. 2.1.18 - Fix scheduling latencies at mount time as well as an endianness bug.
......
...@@ -999,23 +999,11 @@ u64 ntfs_lookup_inode_by_name(ntfs_inode *dir_ni, const ntfschar *uname, ...@@ -999,23 +999,11 @@ u64 ntfs_lookup_inode_by_name(ntfs_inode *dir_ni, const ntfschar *uname,
#endif #endif
typedef union {
INDEX_ROOT *ir;
INDEX_ALLOCATION *ia;
} index_union __attribute__ ((__transparent_union__));
typedef enum {
INDEX_TYPE_ROOT, /* index root */
INDEX_TYPE_ALLOCATION, /* index allocation */
} INDEX_TYPE;
/** /**
* ntfs_filldir - ntfs specific filldir method * ntfs_filldir - ntfs specific filldir method
* @vol: current ntfs volume * @vol: current ntfs volume
* @fpos: position in the directory * @fpos: position in the directory
* @ndir: ntfs inode of current directory * @ndir: ntfs inode of current directory
* @index_type: specifies whether @iu is an index root or an index allocation
* @iu: index root or index allocation attribute to which @ie belongs
* @ia_page: page in which the index allocation buffer @ie is in resides * @ia_page: page in which the index allocation buffer @ie is in resides
* @ie: current index entry * @ie: current index entry
* @name: buffer to use for the converted name * @name: buffer to use for the converted name
...@@ -1036,8 +1024,7 @@ typedef enum { ...@@ -1036,8 +1024,7 @@ typedef enum {
* would need to drop the lock immediately anyway. * would need to drop the lock immediately anyway.
*/ */
static inline int ntfs_filldir(ntfs_volume *vol, loff_t *fpos, static inline int ntfs_filldir(ntfs_volume *vol, loff_t *fpos,
ntfs_inode *ndir, const INDEX_TYPE index_type, ntfs_inode *ndir, struct page *ia_page, INDEX_ENTRY *ie,
index_union iu, struct page *ia_page, INDEX_ENTRY *ie,
u8 *name, void *dirent, filldir_t filldir) u8 *name, void *dirent, filldir_t filldir)
{ {
unsigned long mref; unsigned long mref;
...@@ -1045,14 +1032,6 @@ static inline int ntfs_filldir(ntfs_volume *vol, loff_t *fpos, ...@@ -1045,14 +1032,6 @@ static inline int ntfs_filldir(ntfs_volume *vol, loff_t *fpos,
unsigned dt_type; unsigned dt_type;
FILE_NAME_TYPE_FLAGS name_type; FILE_NAME_TYPE_FLAGS name_type;
/* Advance the position even if going to skip the entry. */
if (index_type == INDEX_TYPE_ALLOCATION)
*fpos = (u8*)ie - (u8*)iu.ia +
(sle64_to_cpu(iu.ia->index_block_vcn) <<
ndir->itype.index.vcn_size_bits) +
vol->mft_record_size;
else /* if (index_type == INDEX_TYPE_ROOT) */
*fpos = (u8*)ie - (u8*)iu.ir;
name_type = ie->key.file_name.file_name_type; name_type = ie->key.file_name.file_name_type;
if (name_type == FILE_NAME_DOS) { if (name_type == FILE_NAME_DOS) {
ntfs_debug("Skipping DOS name space entry."); ntfs_debug("Skipping DOS name space entry.");
...@@ -1084,14 +1063,14 @@ static inline int ntfs_filldir(ntfs_volume *vol, loff_t *fpos, ...@@ -1084,14 +1063,14 @@ static inline int ntfs_filldir(ntfs_volume *vol, loff_t *fpos,
* Drop the page lock otherwise we deadlock with NFS when it calls * Drop the page lock otherwise we deadlock with NFS when it calls
* ->lookup since ntfs_lookup() will lock the same page. * ->lookup since ntfs_lookup() will lock the same page.
*/ */
if (index_type == INDEX_TYPE_ALLOCATION) if (ia_page)
unlock_page(ia_page); unlock_page(ia_page);
ntfs_debug("Calling filldir for %s with len %i, fpos 0x%llx, inode " ntfs_debug("Calling filldir for %s with len %i, fpos 0x%llx, inode "
"0x%lx, DT_%s.", name, name_len, *fpos, mref, "0x%lx, DT_%s.", name, name_len, *fpos, mref,
dt_type == DT_DIR ? "DIR" : "REG"); dt_type == DT_DIR ? "DIR" : "REG");
rc = filldir(dirent, name, name_len, *fpos, mref, dt_type); rc = filldir(dirent, name, name_len, *fpos, mref, dt_type);
/* Relock the page but not if we are aborting ->readdir. */ /* Relock the page but not if we are aborting ->readdir. */
if (!rc && index_type == INDEX_TYPE_ALLOCATION) if (!rc && ia_page)
lock_page(ia_page); lock_page(ia_page);
return rc; return rc;
} }
...@@ -1244,9 +1223,11 @@ static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -1244,9 +1223,11 @@ static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
/* Skip index root entry if continuing previous readdir. */ /* Skip index root entry if continuing previous readdir. */
if (ir_pos > (u8*)ie - (u8*)ir) if (ir_pos > (u8*)ie - (u8*)ir)
continue; continue;
/* Advance the position even if going to skip the entry. */
fpos = (u8*)ie - (u8*)ir;
/* Submit the name to the filldir callback. */ /* Submit the name to the filldir callback. */
rc = ntfs_filldir(vol, &fpos, ndir, INDEX_TYPE_ROOT, ir, NULL, rc = ntfs_filldir(vol, &fpos, ndir, NULL, ie, name, dirent,
ie, name, dirent, filldir); filldir);
if (rc) { if (rc) {
kfree(ir); kfree(ir);
goto abort; goto abort;
...@@ -1420,14 +1401,19 @@ static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -1420,14 +1401,19 @@ static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
/* Skip index block entry if continuing previous readdir. */ /* Skip index block entry if continuing previous readdir. */
if (ia_pos - ia_start > (u8*)ie - (u8*)ia) if (ia_pos - ia_start > (u8*)ie - (u8*)ia)
continue; continue;
/* Advance the position even if going to skip the entry. */
fpos = (u8*)ie - (u8*)ia +
(sle64_to_cpu(ia->index_block_vcn) <<
ndir->itype.index.vcn_size_bits) +
vol->mft_record_size;
/* /*
* Submit the name to the @filldir callback. Note, * Submit the name to the @filldir callback. Note,
* ntfs_filldir() drops the lock on @ia_page but it retakes it * ntfs_filldir() drops the lock on @ia_page but it retakes it
* before returning, unless a non-zero value is returned in * before returning, unless a non-zero value is returned in
* which case the page is left unlocked. * which case the page is left unlocked.
*/ */
rc = ntfs_filldir(vol, &fpos, ndir, INDEX_TYPE_ALLOCATION, ia, rc = ntfs_filldir(vol, &fpos, ndir, ia_page, ie, name, dirent,
ia_page, ie, name, dirent, filldir); filldir);
if (rc) { if (rc) {
/* @ia_page is already unlocked in this case. */ /* @ia_page is already unlocked in this case. */
ntfs_unmap_page(ia_page); ntfs_unmap_page(ia_page);
......
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