From: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
To: Andrew Morton <akpm@osdl.org>
Cc: linux-kernel@vger.kernel.org
Subject: [PATCH 10/29] FAT: Add fat_remove_entries()
Date: Sun, 06 Mar 2005 03:49:05 +0900 [thread overview]
Message-ID: <87ekeuq672.fsf_-_@devron.myhome.or.jp> (raw)
In-Reply-To: <87is46q68d.fsf_-_@devron.myhome.or.jp> (OGAWA Hirofumi's message of "Sun, 06 Mar 2005 03:48:18 +0900")
This changes the fat_slot_info->nr_slot, now it's total counts which
include a shortname entry. And this adds a fat_remove_entries()
which use the ->nr_slots.
In order not to write out the same block repeatedly,
fat_remove_entries() was rewritten from vfat_remove_entries().
Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
---
fs/fat/dir.c | 103 +++++++++++++++++++++++++++++++++++++++++++----
fs/vfat/namei.c | 81 ++++++++++++------------------------
include/linux/msdos_fs.h | 1
3 files changed, 124 insertions(+), 61 deletions(-)
diff -puN fs/fat/dir.c~sync06-fat_dir-cleanup3 fs/fat/dir.c
--- linux-2.6.11/fs/fat/dir.c~sync06-fat_dir-cleanup3 2005-03-06 02:36:28.000000000 +0900
+++ linux-2.6.11-hirofumi/fs/fat/dir.c 2005-03-06 02:36:29.000000000 +0900
@@ -144,7 +144,7 @@ int fat_search_long(struct inode *inode,
struct nls_table *nls_io = MSDOS_SB(sb)->nls_io;
struct nls_table *nls_disk = MSDOS_SB(sb)->nls_disk;
wchar_t bufuname[14];
- unsigned char xlate_len, long_slots;
+ unsigned char xlate_len, nr_slots;
wchar_t *unicode = NULL;
unsigned char work[8], bufname[260]; /* 256 + 4 */
int uni_xlate = MSDOS_SB(sb)->options.unicode_xlate;
@@ -159,7 +159,7 @@ int fat_search_long(struct inode *inode,
if (fat_get_entry(inode, &cpos, &bh, &de, &i_pos) == -1)
goto EODir;
parse_record:
- long_slots = 0;
+ nr_slots = 0;
if (de->name[0] == DELETED_FLAG)
continue;
if (de->attr != ATTR_EXT && (de->attr & ATTR_VOLUME))
@@ -191,7 +191,7 @@ parse_long:
slots = id & ~0x40;
if (slots > 20 || !slots) /* ceil(256 * 2 / 26) */
continue;
- long_slots = slots;
+ nr_slots = slots;
alias_checksum = ds->alias_checksum;
slot = slots;
@@ -228,7 +228,7 @@ parse_long:
for (sum = 0, i = 0; i < 11; i++)
sum = (((sum&1)<<7)|((sum&0xfe)>>1)) + de->name[i];
if (sum != alias_checksum)
- long_slots = 0;
+ nr_slots = 0;
}
memcpy(work, de->name, sizeof(de->name));
@@ -276,7 +276,7 @@ parse_long:
xlate_len)))
goto Found;
- if (long_slots) {
+ if (nr_slots) {
xlate_len = utf8
?utf8_wcstombs(bufname, unicode, sizeof(bufname))
:uni16_to_x8(bufname, unicode, uni_xlate, nls_io);
@@ -290,9 +290,10 @@ parse_long:
}
Found:
+ nr_slots++; /* include the de */
sinfo->i_pos = i_pos;
- sinfo->slot_off = cpos - (long_slots + 1) * sizeof(*de);
- sinfo->nr_slots = long_slots;
+ sinfo->slot_off = cpos - nr_slots * sizeof(*de);
+ sinfo->nr_slots = nr_slots;
sinfo->de = de;
sinfo->bh = bh;
err = 0;
@@ -759,6 +760,94 @@ int fat_scan(struct inode *dir, const un
EXPORT_SYMBOL(fat_scan);
+static int __fat_remove_entries(struct inode *dir, loff_t pos, int nr_slots)
+{
+ struct super_block *sb = dir->i_sb;
+ struct buffer_head *bh;
+ struct msdos_dir_entry *de, *endp;
+ loff_t i_pos;
+ int err = 0, orig_slots;
+
+ while (nr_slots) {
+ bh = NULL;
+ if (fat_get_entry(dir, &pos, &bh, &de, &i_pos) < 0) {
+ err = -EIO;
+ break;
+ }
+
+ orig_slots = nr_slots;
+ endp = (struct msdos_dir_entry *)(bh->b_data + sb->s_blocksize);
+ while (nr_slots && de < endp) {
+ de->name[0] = DELETED_FLAG;
+ de++;
+ nr_slots--;
+ }
+ mark_buffer_dirty(bh);
+ if (IS_DIRSYNC(dir))
+ err = sync_dirty_buffer(bh);
+ brelse(bh);
+ if (err)
+ break;
+
+ /* pos is *next* de's position, so this does `- sizeof(de)' */
+ pos += ((orig_slots - nr_slots) * sizeof(*de)) - sizeof(*de);
+ }
+
+ return err;
+}
+
+int fat_remove_entries(struct inode *dir, struct fat_slot_info *sinfo)
+{
+ struct msdos_dir_entry *de;
+ struct buffer_head *bh;
+ int err = 0, nr_slots;
+
+ /*
+ * First stage: Remove the shortname. By this, the directory
+ * entry is removed.
+ */
+ nr_slots = sinfo->nr_slots;
+ de = sinfo->de;
+ sinfo->de = NULL;
+ bh = sinfo->bh;
+ sinfo->bh = NULL;
+ while (nr_slots && de >= (struct msdos_dir_entry *)bh->b_data) {
+ de->name[0] = DELETED_FLAG;
+ de--;
+ nr_slots--;
+ }
+ mark_buffer_dirty(bh);
+ if (IS_DIRSYNC(dir))
+ err = sync_dirty_buffer(bh);
+ brelse(bh);
+ if (err)
+ return err;
+ dir->i_version++;
+
+ if (nr_slots) {
+ /*
+ * Second stage: remove the remaining longname slots.
+ * (This directory entry is already removed, and so return
+ * the success)
+ */
+ err = __fat_remove_entries(dir, sinfo->slot_off, nr_slots);
+ if (err) {
+ printk(KERN_WARNING
+ "FAT: Couldn't remove the long name slots\n");
+ }
+ }
+
+ dir->i_mtime = dir->i_atime = CURRENT_TIME_SEC;
+ if (IS_DIRSYNC(dir))
+ (void)fat_sync_inode(dir);
+ else
+ mark_inode_dirty(dir);
+
+ return 0;
+}
+
+EXPORT_SYMBOL(fat_remove_entries);
+
static struct buffer_head *fat_extend_dir(struct inode *inode)
{
struct super_block *sb = inode->i_sb;
diff -puN fs/vfat/namei.c~sync06-fat_dir-cleanup3 fs/vfat/namei.c
--- linux-2.6.11/fs/vfat/namei.c~sync06-fat_dir-cleanup3 2005-03-06 02:36:28.000000000 +0900
+++ linux-2.6.11-hirofumi/fs/vfat/namei.c 2005-03-06 02:36:29.000000000 +0900
@@ -721,7 +721,7 @@ static int vfat_add_entry(struct inode *
/* slots can't be less than 1 */
sinfo->slot_off = offset - sizeof(struct msdos_dir_slot) * slots;
- sinfo->nr_slots = slots - 1;
+ sinfo->nr_slots = slots;
sinfo->de = de;
sinfo->bh = bh;
@@ -817,39 +817,6 @@ out:
return res;
}
-static void vfat_remove_entry(struct inode *dir, struct fat_slot_info *sinfo)
-{
- struct super_block *sb = dir->i_sb;
- struct msdos_dir_entry *de = sinfo->de;
- struct buffer_head *bh = sinfo->bh;
- loff_t offset, i_pos;
- int i;
-
- dir->i_mtime = dir->i_atime = CURRENT_TIME_SEC;
- dir->i_version++;
- mark_inode_dirty(dir);
-
- /* remove the shortname */
- de->name[0] = DELETED_FLAG;
- mark_buffer_dirty(bh);
- if (sb->s_flags & MS_SYNCHRONOUS)
- sync_dirty_buffer(bh);
-
- /* remove the longname */
- offset = sinfo->slot_off;
- de = NULL;
- for (i = sinfo->nr_slots; i > 0; --i) {
- if (fat_get_entry(dir, &offset, &bh, &de, &i_pos) < 0)
- continue;
- de->name[0] = DELETED_FLAG;
- de->attr = ATTR_NONE;
- mark_buffer_dirty(bh);
- if (sb->s_flags & MS_SYNCHRONOUS)
- sync_dirty_buffer(bh);
- }
- brelse(bh);
-}
-
static int vfat_rmdir(struct inode *dir, struct dentry *dentry)
{
struct inode *inode = dentry->d_inode;
@@ -865,14 +832,15 @@ static int vfat_rmdir(struct inode *dir,
if (err)
goto out;
+ err = fat_remove_entries(dir, &sinfo); /* and releases bh */
+ if (err)
+ goto out;
+ dir->i_nlink--;
+
inode->i_nlink = 0;
inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC;
fat_detach(inode);
mark_inode_dirty(inode);
- /* releases bh and syncs it if necessary */
- vfat_remove_entry(dir, &sinfo);
-
- dir->i_nlink--;
out:
unlock_kernel();
@@ -891,12 +859,13 @@ static int vfat_unlink(struct inode *dir
if (err)
goto out;
+ err = fat_remove_entries(dir, &sinfo); /* and releases bh */
+ if (err)
+ goto out;
inode->i_nlink = 0;
inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC;
fat_detach(inode);
mark_inode_dirty(inode);
- /* releases bh and syncs it if necessary */
- vfat_remove_entry(dir, &sinfo);
out:
unlock_kernel();
@@ -939,8 +908,7 @@ mkdir_failed:
inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC;
fat_detach(inode);
mark_inode_dirty(inode);
- /* releases bh ands syncs if necessary */
- vfat_remove_entry(dir, &sinfo);
+ fat_remove_entries(dir, &sinfo); /* and releases bh */
iput(inode);
dir->i_nlink--;
goto out;
@@ -956,49 +924,56 @@ static int vfat_rename(struct inode *old
int err, is_dir;
struct fat_slot_info old_sinfo, sinfo;
- old_sinfo.bh = sinfo.bh = dotdot_bh = NULL;
+ old_sinfo.bh = dotdot_bh = NULL;
old_inode = old_dentry->d_inode;
new_inode = new_dentry->d_inode;
lock_kernel();
err = vfat_find(old_dir, &old_dentry->d_name, &old_sinfo);
if (err)
- goto rename_done;
+ goto out;
is_dir = S_ISDIR(old_inode->i_mode);
if (is_dir) {
if (fat_scan(old_inode, MSDOS_DOTDOT, &dotdot_bh,
&dotdot_de, &dotdot_i_pos) < 0) {
err = -EIO;
- goto rename_done;
+ goto out;
}
}
if (new_dentry->d_inode) {
err = vfat_find(new_dir, &new_dentry->d_name, &sinfo);
- if (err || MSDOS_I(new_inode)->i_pos != sinfo.i_pos) {
+ if (err)
+ goto out;
+ brelse(sinfo.bh);
+ if (MSDOS_I(new_inode)->i_pos != sinfo.i_pos) {
/* WTF??? Cry and fail. */
printk(KERN_WARNING "vfat_rename: fs corrupted\n");
- goto rename_done;
+ goto out;
}
if (is_dir) {
err = fat_dir_empty(new_inode);
if (err)
- goto rename_done;
+ goto out;
}
fat_detach(new_inode);
} else {
err = vfat_add_entry(new_dir, &new_dentry->d_name, is_dir,
&sinfo);
if (err)
- goto rename_done;
+ goto out;
+ brelse(sinfo.bh);
}
-
new_dir->i_version++;
/* releases old_bh */
- vfat_remove_entry(old_dir, &old_sinfo);
+ err = fat_remove_entries(old_dir, &old_sinfo); /* and releases bh */
old_sinfo.bh = NULL;
+ if (err)
+ goto out;
+ if (is_dir)
+ old_dir->i_nlink--;
fat_detach(old_inode);
fat_attach(old_inode, sinfo.i_pos);
mark_inode_dirty(old_inode);
@@ -1019,7 +994,6 @@ static int vfat_rename(struct inode *old
if (new_dir->i_sb->s_flags & MS_SYNCHRONOUS)
sync_dirty_buffer(dotdot_bh);
- old_dir->i_nlink--;
if (new_inode) {
new_inode->i_nlink--;
} else {
@@ -1027,10 +1001,9 @@ static int vfat_rename(struct inode *old
mark_inode_dirty(new_dir);
}
}
-rename_done:
+out:
brelse(dotdot_bh);
brelse(old_sinfo.bh);
- brelse(sinfo.bh);
unlock_kernel();
return err;
diff -puN include/linux/msdos_fs.h~sync06-fat_dir-cleanup3 include/linux/msdos_fs.h
--- linux-2.6.11/include/linux/msdos_fs.h~sync06-fat_dir-cleanup3 2005-03-06 02:36:28.000000000 +0900
+++ linux-2.6.11-hirofumi/include/linux/msdos_fs.h 2005-03-06 02:36:29.000000000 +0900
@@ -333,6 +333,7 @@ extern int fat_subdirs(struct inode *dir
extern int fat_scan(struct inode *dir, const unsigned char *name,
struct buffer_head **res_bh,
struct msdos_dir_entry **res_de, loff_t *i_pos);
+extern int fat_remove_entries(struct inode *dir, struct fat_slot_info *sinfo);
/* fat/fatent.c */
struct fat_entry {
_
next prev parent reply other threads:[~2005-03-05 19:40 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <87ll92rl6a.fsf@devron.myhome.or.jp>
2005-03-05 18:41 ` [PATCH 1/29] fat: fix writev(), add aio support OGAWA Hirofumi
2005-03-05 18:42 ` [PATCH 2/29] FAT: Updated FAT attributes patch OGAWA Hirofumi
2005-03-05 18:43 ` [PATCH 3/29] FAT: fat_readdirx() with dotOK=yes fix OGAWA Hirofumi
2005-03-05 18:43 ` [PATCH 4/29] let fat handle MS_SYNCHRONOUS flag OGAWA Hirofumi
2005-03-06 22:38 ` Christoph Hellwig
2005-03-07 14:56 ` OGAWA Hirofumi
2005-03-05 18:44 ` [PATCH 5/29] FAT: Rewrite the FAT (File Allocation Table) access stuff OGAWA Hirofumi
2005-03-05 18:45 ` [PATCH 6/29] FAT: add debugging code to fatent.c OGAWA Hirofumi
2005-03-05 18:47 ` [PATCH 7/29] FAT: Use "unsigned int" for ->free_clusters and ->prev_free OGAWA Hirofumi
2005-03-05 18:47 ` [PATCH 8/29] FAT: "struct vfat_slot_info" cleanup OGAWA Hirofumi
2005-03-05 18:48 ` [PATCH 9/29] FAT: Use "struct fat_slot_info" for fat_search_long() OGAWA Hirofumi
2005-03-05 18:49 ` OGAWA Hirofumi [this message]
2005-03-05 18:49 ` [PATCH 11/29] FAT: fat_build_inode() cleanup OGAWA Hirofumi
2005-03-05 18:50 ` [PATCH 12/29] FAT: Use "struct fat_slot_info" for fat_scan() OGAWA Hirofumi
2005-03-05 18:50 ` [PATCH 13/29] FAT: Use "struct fat_slot_info" for msdos_find() OGAWA Hirofumi
2005-03-05 18:51 ` [PATCH 14/29] FAT: vfat_build_slots() cleanup OGAWA Hirofumi
2005-03-05 18:52 ` [PATCH 15/29] FAT: Use a same timestamp on some operations path OGAWA Hirofumi
2005-03-05 18:52 ` [PATCH 16/29] FAT: msdos_rename() cleanup OGAWA Hirofumi
2005-03-05 18:53 ` [PATCH 17/29] FAT: msdos_add_entry() cleanup OGAWA Hirofumi
2005-03-05 18:53 ` [PATCH 18/29] FAT: Allocate the cluster before adding the directory entry OGAWA Hirofumi
2005-03-05 18:54 ` [PATCH 19/29] FAT: Rewrite fat_add_entries() OGAWA Hirofumi
2005-03-05 18:55 ` [PATCH 20/29] FAT: Use fat_remove_entries() for msdos OGAWA Hirofumi
2005-03-05 18:55 ` [PATCH 21/29] FAT: make the fat_get_entry()/fat__get_entry() the static OGAWA Hirofumi
2005-03-05 18:56 ` [PATCH 22/29] FAT: "i_pos" cleanup OGAWA Hirofumi
2005-03-05 18:56 ` [PATCH 23/29] FAT: Remove the multiple MSDOS_SB() call OGAWA Hirofumi
2005-03-05 18:57 ` [PATCH 24/29] FAT: Remove unneed mark_inode_dirty() OGAWA Hirofumi
2005-03-05 18:57 ` [PATCH 25/29] FAT: Fix fat_truncate() OGAWA Hirofumi
2005-03-05 18:58 ` [PATCH 26/29] FAT: Fix fat_write_inode() OGAWA Hirofumi
2005-03-05 18:58 ` [PATCH 27/29] FAT: Use synchronous update for {vfat,msdos}_add_entry() OGAWA Hirofumi
2005-03-05 18:59 ` [PATCH 28/29] FAT: Update ->rename() path OGAWA Hirofumi
2005-03-05 19:00 ` [PATCH 29/29] FAT: Fix typo OGAWA Hirofumi
2005-03-06 22:44 ` [PATCH 23/29] FAT: Remove the multiple MSDOS_SB() call Christoph Hellwig
2005-03-07 22:01 ` Adrian Bunk
2005-03-08 13:48 ` OGAWA Hirofumi
2005-03-06 15:53 ` [PATCH 2/29] FAT: Updated FAT attributes patch Michael Geng
2005-03-06 17:02 ` OGAWA Hirofumi
2005-03-06 22:45 ` Christoph Hellwig
2005-03-06 0:07 ` [PATCH] FAT: Support synchronous updates OGAWA Hirofumi
2005-03-07 1:10 ` [PATCH] FAT: Support synchronous update Andrew Morton
2005-03-07 15:02 ` OGAWA Hirofumi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87ekeuq672.fsf_-_@devron.myhome.or.jp \
--to=hirofumi@mail.parknet.co.jp \
--cc=akpm@osdl.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox