lkml.org 
[lkml]   [2003]   [Jul]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Subject[PATCH] fat_access cleanup (4/11)
From
Date
This removes dirty raw_scan_*(), and rewrites fat_scan() and
fat_subdirs() by useing fat_get_entry() instead.


fs/fat/inode.c | 1
fs/fat/misc.c | 247 +++++++++------------------------------------------------
2 files changed, 40 insertions(+), 208 deletions(-)

diff -puN fs/fat/inode.c~fat_access-cleanup1 fs/fat/inode.c
--- linux-2.6.0-test1/fs/fat/inode.c~fat_access-cleanup1 2003-07-21 02:48:16.000000000 +0900
+++ linux-2.6.0-test1-hirofumi/fs/fat/inode.c 2003-07-21 02:48:16.000000000 +0900
@@ -501,6 +501,7 @@ static int fat_read_root(struct inode *i
struct msdos_sb_info *sbi = MSDOS_SB(sb);
int error;

+ MSDOS_I(inode)->file_cluster = MSDOS_I(inode)->disk_cluster = 0;
MSDOS_I(inode)->i_pos = 0;
inode->i_uid = sbi->options.fs_uid;
inode->i_gid = sbi->options.fs_gid;
diff -puN fs/fat/misc.c~fat_access-cleanup1 fs/fat/misc.c
--- linux-2.6.0-test1/fs/fat/misc.c~fat_access-cleanup1 2003-07-21 02:48:16.000000000 +0900
+++ linux-2.6.0-test1-hirofumi/fs/fat/misc.c 2003-07-21 02:48:16.000000000 +0900
@@ -326,230 +326,61 @@ next:
return 0;
}

-
-/*
- * Now an ugly part: this set of directory scan routines works on clusters
- * rather than on inodes and sectors. They are necessary to locate the '..'
- * directory "inode". raw_scan_sector operates in four modes:
- *
- * name number ino action
- * -------- -------- -------- -------------------------------------------------
- * non-NULL - X Find an entry with that name
- * NULL non-NULL non-NULL Find an entry whose data starts at *number
- * NULL non-NULL NULL Count subdirectories in *number. (*)
- * NULL NULL non-NULL Find an empty entry
- *
- * (*) The return code should be ignored. It DOES NOT indicate success or
- * failure. *number has to be initialized to zero.
- *
- * - = not used, X = a value is returned unless NULL
- *
- * If res_bh is non-NULL, the buffer is not deallocated but returned to the
- * caller on success. res_de is set accordingly.
- *
- * If cont is non-zero, raw_found continues with the entry after the one
- * res_bh/res_de point to.
- */
-
-
-#define RSS_NAME /* search for name */ \
- done = !strncmp(data[entry].name,name,MSDOS_NAME) && \
- !(data[entry].attr & ATTR_VOLUME);
-
-#define RSS_START /* search for start cluster */ \
- done = !IS_FREE(data[entry].name) \
- && ( \
- ( \
- (sbi->fat_bits != 32) ? 0 : (CF_LE_W(data[entry].starthi) << 16) \
- ) \
- | CF_LE_W(data[entry].start) \
- ) == *number;
-
-#define RSS_FREE /* search for free entry */ \
- { \
- done = IS_FREE(data[entry].name); \
- }
-
-#define RSS_COUNT /* count subdirectories */ \
- { \
- done = 0; \
- if (!IS_FREE(data[entry].name) && (data[entry].attr & ATTR_DIR)) \
- (*number)++; \
- }
-
-static int raw_scan_sector(struct super_block *sb, sector_t sector,
- const char *name, int *number, loff_t *i_pos,
- struct buffer_head **res_bh,
- struct msdos_dir_entry **res_de)
-{
- struct msdos_sb_info *sbi = MSDOS_SB(sb);
- struct buffer_head *bh;
- struct msdos_dir_entry *data;
- int entry,start,done;
-
- if (!(bh = sb_bread(sb, sector)))
- return -EIO;
- data = (struct msdos_dir_entry *) bh->b_data;
- for (entry = 0; entry < sbi->dir_per_block; entry++) {
-/* RSS_COUNT: if (data[entry].name == name) done=true else done=false. */
- if (name) {
- RSS_NAME
- } else {
- if (!i_pos) RSS_COUNT
- else {
- if (number) RSS_START
- else RSS_FREE
- }
- }
- if (done) {
- if (i_pos) {
- *i_pos = ((loff_t)sector << sbi->dir_per_block_bits) + entry;
- }
- start = CF_LE_W(data[entry].start);
- if (sbi->fat_bits == 32)
- start |= (CF_LE_W(data[entry].starthi) << 16);
-
- if (!res_bh)
- brelse(bh);
- else {
- *res_bh = bh;
- *res_de = &data[entry];
- }
- return start;
- }
- }
- brelse(bh);
- return -ENOENT;
-}
-
-
-/*
- * raw_scan_root performs raw_scan_sector on the root directory until the
- * requested entry is found or the end of the directory is reached.
- */
-
-static int raw_scan_root(struct super_block *sb, const char *name,
- int *number, loff_t *i_pos,
- struct buffer_head **res_bh,
- struct msdos_dir_entry **res_de)
-{
- int count,cluster;
-
- for (count = 0;
- count < MSDOS_SB(sb)->dir_entries / MSDOS_SB(sb)->dir_per_block;
- count++) {
- cluster = raw_scan_sector(sb, MSDOS_SB(sb)->dir_start + count,
- name, number, i_pos, res_bh, res_de);
- if (cluster >= 0)
- return cluster;
- }
- return -ENOENT;
-}
-
-
-/*
- * raw_scan_nonroot performs raw_scan_sector on a non-root directory until the
- * requested entry is found or the end of the directory is reached.
- */
-
-static int raw_scan_nonroot(struct super_block *sb, int start, const char *name,
- int *number, loff_t *i_pos,
- struct buffer_head **res_bh,
- struct msdos_dir_entry **res_de)
-{
- struct msdos_sb_info *sbi = MSDOS_SB(sb);
- int count, cluster;
- unsigned long dir_size = 0;
- sector_t sector;
-
-#ifdef DEBUG
- printk("raw_scan_nonroot: start=%d\n",start);
-#endif
- do {
- for (count = 0; count < sbi->cluster_size; count++) {
- sector = ((sector_t)start - 2) * sbi->cluster_size
- + count + sbi->data_start;
- cluster = raw_scan_sector(sb, sector, name, number,
- i_pos, res_bh, res_de);
- if (cluster >= 0)
- return cluster;
- }
- dir_size += 1 << sbi->cluster_bits;
- if (dir_size > FAT_MAX_DIR_SIZE) {
- fat_fs_panic(sb, "Directory %d: "
+static int fat_get_short_entry(struct inode *dir, loff_t *pos,
+ struct buffer_head **bh,
+ struct msdos_dir_entry **de, loff_t *i_pos)
+{
+ struct super_block *sb = dir->i_sb;
+
+ while (fat_get_entry(dir, pos, bh, de, i_pos) >= 0) {
+ if (*pos >= FAT_MAX_DIR_SIZE) {
+ fat_fs_panic(sb, "Directory %llu: "
"exceeded the maximum size of directory",
- start);
- break;
+ MSDOS_I(dir)->i_pos);
+ return -EIO;
}
- start = fat_access(sb, start, -1);
- if (start < 0)
- return start;
- else if (start == FAT_ENT_FREE) {
- fat_fs_panic(sb, "%s: invalid cluster chain",
- __FUNCTION__);
- break;
- }
-#ifdef DEBUG
- printk("next start: %d\n",start);
-#endif
- } while (start != FAT_ENT_EOF);
-
+ /* free entry or long name entry or volume label */
+ if (!IS_FREE((*de)->name) && !((*de)->attr & ATTR_VOLUME))
+ return 0;
+ }
return -ENOENT;
}

-
-/*
- * raw_scan performs raw_scan_sector on any sector.
- *
- * NOTE: raw_scan must not be used on a directory that is is the process of
- * being created.
- */
-
-static int raw_scan(struct super_block *sb, int start, const char *name,
- loff_t *i_pos, struct buffer_head **res_bh,
- struct msdos_dir_entry **res_de)
-{
- if (start)
- return raw_scan_nonroot(sb,start,name,NULL,i_pos,res_bh,res_de);
- else
- return raw_scan_root(sb,name,NULL,i_pos,res_bh,res_de);
-}
-
/*
* fat_subdirs counts the number of sub-directories of dir. It can be run
* on directories being created.
*/
int fat_subdirs(struct inode *dir)
{
- struct msdos_sb_info *sbi = MSDOS_SB(dir->i_sb);
- int number;
-
- number = 0;
- if ((dir->i_ino == MSDOS_ROOT_INO) && (sbi->fat_bits != 32))
- raw_scan_root(dir->i_sb, NULL, &number, NULL, NULL, NULL);
- else {
- if ((dir->i_ino != MSDOS_ROOT_INO) && !MSDOS_I(dir)->i_start)
- return 0; /* in mkdir */
- else {
- raw_scan_nonroot(dir->i_sb, MSDOS_I(dir)->i_start,
- NULL, &number, NULL, NULL, NULL);
- }
+ struct buffer_head *bh;
+ struct msdos_dir_entry *de;
+ loff_t cpos, i_pos;
+ int count = 0;
+
+ bh = NULL;
+ cpos = 0;
+ while (fat_get_short_entry(dir, &cpos, &bh, &de, &i_pos) >= 0) {
+ if (de->attr & ATTR_DIR)
+ count++;
}
- return number;
+ brelse(bh);
+ return count;
}

-
/*
- * Scans a directory for a given file (name points to its formatted name) or
- * for an empty directory slot (name is NULL). Returns an error code or zero.
+ * Scans a directory for a given file (name points to its formatted name).
+ * Returns an error code or zero.
*/
-
-int fat_scan(struct inode *dir, const char *name, struct buffer_head **res_bh,
- struct msdos_dir_entry **res_de, loff_t *i_pos)
+int fat_scan(struct inode *dir, const char *name, struct buffer_head **bh,
+ struct msdos_dir_entry **de, loff_t *i_pos)
{
- int res;
+ loff_t cpos;

- res = raw_scan(dir->i_sb, MSDOS_I(dir)->i_start, name, i_pos,
- res_bh, res_de);
- return (res < 0) ? res : 0;
+ *bh = NULL;
+ cpos = 0;
+ while (fat_get_short_entry(dir, &cpos, bh, de, i_pos) >= 0) {
+ if (!strncmp((*de)->name, name, MSDOS_NAME))
+ return 0;
+ }
+ return -ENOENT;
}
_

--
OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 13:47    [W:0.030 / U:0.544 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site