aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ntfs/dir.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2013-05-17 21:22:31 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2013-06-29 04:56:48 -0400
commit956ce2083c93c6ce0a8504d000746b1bea4fe111 (patch)
treeee99b10932b5e3b598ba0391f2df7d09723f937f /fs/ntfs/dir.c
parentbfee7169c0210f501a79e4dfdfc309a975775fa6 (diff)
[readdir] convert ntfs
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/ntfs/dir.c')
-rw-r--r--fs/ntfs/dir.c84
1 files changed, 27 insertions, 57 deletions
diff --git a/fs/ntfs/dir.c b/fs/ntfs/dir.c
index aa411c3f20e9..9e38dafa3bc7 100644
--- a/fs/ntfs/dir.c
+++ b/fs/ntfs/dir.c
@@ -1004,13 +1004,11 @@ dir_err_out:
1004/** 1004/**
1005 * ntfs_filldir - ntfs specific filldir method 1005 * ntfs_filldir - ntfs specific filldir method
1006 * @vol: current ntfs volume 1006 * @vol: current ntfs volume
1007 * @fpos: position in the directory
1008 * @ndir: ntfs inode of current directory 1007 * @ndir: ntfs inode of current directory
1009 * @ia_page: page in which the index allocation buffer @ie is in resides 1008 * @ia_page: page in which the index allocation buffer @ie is in resides
1010 * @ie: current index entry 1009 * @ie: current index entry
1011 * @name: buffer to use for the converted name 1010 * @name: buffer to use for the converted name
1012 * @dirent: vfs filldir callback context 1011 * @actor: what to feed the entries to
1013 * @filldir: vfs filldir callback
1014 * 1012 *
1015 * Convert the Unicode @name to the loaded NLS and pass it to the @filldir 1013 * Convert the Unicode @name to the loaded NLS and pass it to the @filldir
1016 * callback. 1014 * callback.
@@ -1024,12 +1022,12 @@ dir_err_out:
1024 * retake the lock if we are returning a non-zero value as ntfs_readdir() 1022 * retake the lock if we are returning a non-zero value as ntfs_readdir()
1025 * would need to drop the lock immediately anyway. 1023 * would need to drop the lock immediately anyway.
1026 */ 1024 */
1027static inline int ntfs_filldir(ntfs_volume *vol, loff_t fpos, 1025static inline int ntfs_filldir(ntfs_volume *vol,
1028 ntfs_inode *ndir, struct page *ia_page, INDEX_ENTRY *ie, 1026 ntfs_inode *ndir, struct page *ia_page, INDEX_ENTRY *ie,
1029 u8 *name, void *dirent, filldir_t filldir) 1027 u8 *name, struct dir_context *actor)
1030{ 1028{
1031 unsigned long mref; 1029 unsigned long mref;
1032 int name_len, rc; 1030 int name_len;
1033 unsigned dt_type; 1031 unsigned dt_type;
1034 FILE_NAME_TYPE_FLAGS name_type; 1032 FILE_NAME_TYPE_FLAGS name_type;
1035 1033
@@ -1068,13 +1066,14 @@ static inline int ntfs_filldir(ntfs_volume *vol, loff_t fpos,
1068 if (ia_page) 1066 if (ia_page)
1069 unlock_page(ia_page); 1067 unlock_page(ia_page);
1070 ntfs_debug("Calling filldir for %s with len %i, fpos 0x%llx, inode " 1068 ntfs_debug("Calling filldir for %s with len %i, fpos 0x%llx, inode "
1071 "0x%lx, DT_%s.", name, name_len, fpos, mref, 1069 "0x%lx, DT_%s.", name, name_len, actor->pos, mref,
1072 dt_type == DT_DIR ? "DIR" : "REG"); 1070 dt_type == DT_DIR ? "DIR" : "REG");
1073 rc = filldir(dirent, name, name_len, fpos, mref, dt_type); 1071 if (!dir_emit(actor, name, name_len, mref, dt_type))
1072 return 1;
1074 /* Relock the page but not if we are aborting ->readdir. */ 1073 /* Relock the page but not if we are aborting ->readdir. */
1075 if (!rc && ia_page) 1074 if (ia_page)
1076 lock_page(ia_page); 1075 lock_page(ia_page);
1077 return rc; 1076 return 0;
1078} 1077}
1079 1078
1080/* 1079/*
@@ -1097,11 +1096,11 @@ static inline int ntfs_filldir(ntfs_volume *vol, loff_t fpos,
1097 * removes them again after the write is complete after which it 1096 * removes them again after the write is complete after which it
1098 * unlocks the page. 1097 * unlocks the page.
1099 */ 1098 */
1100static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir) 1099static int ntfs_readdir(struct file *file, struct dir_context *actor)
1101{ 1100{
1102 s64 ia_pos, ia_start, prev_ia_pos, bmp_pos; 1101 s64 ia_pos, ia_start, prev_ia_pos, bmp_pos;
1103 loff_t fpos, i_size; 1102 loff_t i_size;
1104 struct inode *bmp_vi, *vdir = file_inode(filp); 1103 struct inode *bmp_vi, *vdir = file_inode(file);
1105 struct super_block *sb = vdir->i_sb; 1104 struct super_block *sb = vdir->i_sb;
1106 ntfs_inode *ndir = NTFS_I(vdir); 1105 ntfs_inode *ndir = NTFS_I(vdir);
1107 ntfs_volume *vol = NTFS_SB(sb); 1106 ntfs_volume *vol = NTFS_SB(sb);
@@ -1116,33 +1115,16 @@ static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
1116 u8 *kaddr, *bmp, *index_end; 1115 u8 *kaddr, *bmp, *index_end;
1117 ntfs_attr_search_ctx *ctx; 1116 ntfs_attr_search_ctx *ctx;
1118 1117
1119 fpos = filp->f_pos;
1120 ntfs_debug("Entering for inode 0x%lx, fpos 0x%llx.", 1118 ntfs_debug("Entering for inode 0x%lx, fpos 0x%llx.",
1121 vdir->i_ino, fpos); 1119 vdir->i_ino, actor->pos);
1122 rc = err = 0; 1120 rc = err = 0;
1123 /* Are we at end of dir yet? */ 1121 /* Are we at end of dir yet? */
1124 i_size = i_size_read(vdir); 1122 i_size = i_size_read(vdir);
1125 if (fpos >= i_size + vol->mft_record_size) 1123 if (actor->pos >= i_size + vol->mft_record_size)
1126 goto done; 1124 return 0;
1127 /* Emulate . and .. for all directories. */ 1125 /* Emulate . and .. for all directories. */
1128 if (!fpos) { 1126 if (!dir_emit_dots(file, actor))
1129 ntfs_debug("Calling filldir for . with len 1, fpos 0x0, " 1127 return 0;
1130 "inode 0x%lx, DT_DIR.", vdir->i_ino);
1131 rc = filldir(dirent, ".", 1, fpos, vdir->i_ino, DT_DIR);
1132 if (rc)
1133 goto done;
1134 fpos++;
1135 }
1136 if (fpos == 1) {
1137 ntfs_debug("Calling filldir for .. with len 2, fpos 0x1, "
1138 "inode 0x%lx, DT_DIR.",
1139 (unsigned long)parent_ino(filp->f_path.dentry));
1140 rc = filldir(dirent, "..", 2, fpos,
1141 parent_ino(filp->f_path.dentry), DT_DIR);
1142 if (rc)
1143 goto done;
1144 fpos++;
1145 }
1146 m = NULL; 1128 m = NULL;
1147 ctx = NULL; 1129 ctx = NULL;
1148 /* 1130 /*
@@ -1155,7 +1137,7 @@ static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
1155 goto err_out; 1137 goto err_out;
1156 } 1138 }
1157 /* Are we jumping straight into the index allocation attribute? */ 1139 /* Are we jumping straight into the index allocation attribute? */
1158 if (fpos >= vol->mft_record_size) 1140 if (actor->pos >= vol->mft_record_size)
1159 goto skip_index_root; 1141 goto skip_index_root;
1160 /* Get hold of the mft record for the directory. */ 1142 /* Get hold of the mft record for the directory. */
1161 m = map_mft_record(ndir); 1143 m = map_mft_record(ndir);
@@ -1170,7 +1152,7 @@ static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
1170 goto err_out; 1152 goto err_out;
1171 } 1153 }
1172 /* Get the offset into the index root attribute. */ 1154 /* Get the offset into the index root attribute. */
1173 ir_pos = (s64)fpos; 1155 ir_pos = (s64)actor->pos;
1174 /* Find the index root attribute in the mft record. */ 1156 /* Find the index root attribute in the mft record. */
1175 err = ntfs_attr_lookup(AT_INDEX_ROOT, I30, 4, CASE_SENSITIVE, 0, NULL, 1157 err = ntfs_attr_lookup(AT_INDEX_ROOT, I30, 4, CASE_SENSITIVE, 0, NULL,
1176 0, ctx); 1158 0, ctx);
@@ -1226,10 +1208,9 @@ static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
1226 if (ir_pos > (u8*)ie - (u8*)ir) 1208 if (ir_pos > (u8*)ie - (u8*)ir)
1227 continue; 1209 continue;
1228 /* Advance the position even if going to skip the entry. */ 1210 /* Advance the position even if going to skip the entry. */
1229 fpos = (u8*)ie - (u8*)ir; 1211 actor->pos = (u8*)ie - (u8*)ir;
1230 /* Submit the name to the filldir callback. */ 1212 /* Submit the name to the filldir callback. */
1231 rc = ntfs_filldir(vol, fpos, ndir, NULL, ie, name, dirent, 1213 rc = ntfs_filldir(vol, ndir, NULL, ie, name, actor);
1232 filldir);
1233 if (rc) { 1214 if (rc) {
1234 kfree(ir); 1215 kfree(ir);
1235 goto abort; 1216 goto abort;
@@ -1242,12 +1223,12 @@ static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
1242 if (!NInoIndexAllocPresent(ndir)) 1223 if (!NInoIndexAllocPresent(ndir))
1243 goto EOD; 1224 goto EOD;
1244 /* Advance fpos to the beginning of the index allocation. */ 1225 /* Advance fpos to the beginning of the index allocation. */
1245 fpos = vol->mft_record_size; 1226 actor->pos = vol->mft_record_size;
1246skip_index_root: 1227skip_index_root:
1247 kaddr = NULL; 1228 kaddr = NULL;
1248 prev_ia_pos = -1LL; 1229 prev_ia_pos = -1LL;
1249 /* Get the offset into the index allocation attribute. */ 1230 /* Get the offset into the index allocation attribute. */
1250 ia_pos = (s64)fpos - vol->mft_record_size; 1231 ia_pos = (s64)actor->pos - vol->mft_record_size;
1251 ia_mapping = vdir->i_mapping; 1232 ia_mapping = vdir->i_mapping;
1252 ntfs_debug("Inode 0x%lx, getting index bitmap.", vdir->i_ino); 1233 ntfs_debug("Inode 0x%lx, getting index bitmap.", vdir->i_ino);
1253 bmp_vi = ntfs_attr_iget(vdir, AT_BITMAP, I30, 4); 1234 bmp_vi = ntfs_attr_iget(vdir, AT_BITMAP, I30, 4);
@@ -1409,7 +1390,7 @@ find_next_index_buffer:
1409 if (ia_pos - ia_start > (u8*)ie - (u8*)ia) 1390 if (ia_pos - ia_start > (u8*)ie - (u8*)ia)
1410 continue; 1391 continue;
1411 /* Advance the position even if going to skip the entry. */ 1392 /* Advance the position even if going to skip the entry. */
1412 fpos = (u8*)ie - (u8*)ia + 1393 actor->pos = (u8*)ie - (u8*)ia +
1413 (sle64_to_cpu(ia->index_block_vcn) << 1394 (sle64_to_cpu(ia->index_block_vcn) <<
1414 ndir->itype.index.vcn_size_bits) + 1395 ndir->itype.index.vcn_size_bits) +
1415 vol->mft_record_size; 1396 vol->mft_record_size;
@@ -1419,8 +1400,7 @@ find_next_index_buffer:
1419 * before returning, unless a non-zero value is returned in 1400 * before returning, unless a non-zero value is returned in
1420 * which case the page is left unlocked. 1401 * which case the page is left unlocked.
1421 */ 1402 */
1422 rc = ntfs_filldir(vol, fpos, ndir, ia_page, ie, name, dirent, 1403 rc = ntfs_filldir(vol, ndir, ia_page, ie, name, actor);
1423 filldir);
1424 if (rc) { 1404 if (rc) {
1425 /* @ia_page is already unlocked in this case. */ 1405 /* @ia_page is already unlocked in this case. */
1426 ntfs_unmap_page(ia_page); 1406 ntfs_unmap_page(ia_page);
@@ -1439,18 +1419,9 @@ unm_EOD:
1439 iput(bmp_vi); 1419 iput(bmp_vi);
1440EOD: 1420EOD:
1441 /* We are finished, set fpos to EOD. */ 1421 /* We are finished, set fpos to EOD. */
1442 fpos = i_size + vol->mft_record_size; 1422 actor->pos = i_size + vol->mft_record_size;
1443abort: 1423abort:
1444 kfree(name); 1424 kfree(name);
1445done:
1446#ifdef DEBUG
1447 if (!rc)
1448 ntfs_debug("EOD, fpos 0x%llx, returning 0.", fpos);
1449 else
1450 ntfs_debug("filldir returned %i, fpos 0x%llx, returning 0.",
1451 rc, fpos);
1452#endif
1453 filp->f_pos = fpos;
1454 return 0; 1425 return 0;
1455err_out: 1426err_out:
1456 if (bmp_page) { 1427 if (bmp_page) {
@@ -1471,7 +1442,6 @@ iput_err_out:
1471 if (!err) 1442 if (!err)
1472 err = -EIO; 1443 err = -EIO;
1473 ntfs_debug("Failed. Returning error code %i.", -err); 1444 ntfs_debug("Failed. Returning error code %i.", -err);
1474 filp->f_pos = fpos;
1475 return err; 1445 return err;
1476} 1446}
1477 1447
@@ -1571,7 +1541,7 @@ static int ntfs_dir_fsync(struct file *filp, loff_t start, loff_t end,
1571const struct file_operations ntfs_dir_ops = { 1541const struct file_operations ntfs_dir_ops = {
1572 .llseek = generic_file_llseek, /* Seek inside directory. */ 1542 .llseek = generic_file_llseek, /* Seek inside directory. */
1573 .read = generic_read_dir, /* Return -EISDIR. */ 1543 .read = generic_read_dir, /* Return -EISDIR. */
1574 .readdir = ntfs_readdir, /* Read directory contents. */ 1544 .iterate = ntfs_readdir, /* Read directory contents. */
1575#ifdef NTFS_RW 1545#ifdef NTFS_RW
1576 .fsync = ntfs_dir_fsync, /* Sync a directory to disk. */ 1546 .fsync = ntfs_dir_fsync, /* Sync a directory to disk. */
1577 /*.aio_fsync = ,*/ /* Sync all outstanding async 1547 /*.aio_fsync = ,*/ /* Sync all outstanding async