mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 1/9] fat: kill is_bad_inode() check
@ 2008-04-20 18:13 OGAWA Hirofumi
  2008-04-20 18:13 ` [PATCH 2/9] fat: fat_notify_change() and check_mode() cleanup OGAWA Hirofumi
  0 siblings, 1 reply; 9+ messages in thread
From: OGAWA Hirofumi @ 2008-04-20 18:13 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, hirofumi


FAT doesn't need to check bad inode anymore.

Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
---

 fs/fat/inode.c |    9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff -puN fs/fat/inode.c~fat-cleanup-bad-inode fs/fat/inode.c
--- linux-2.6/fs/fat/inode.c~fat-cleanup-bad-inode	2008-02-15 17:44:56.000000000 +0900
+++ linux-2.6-hirofumi/fs/fat/inode.c	2008-02-15 17:44:56.000000000 +0900
@@ -433,11 +433,8 @@ EXPORT_SYMBOL_GPL(fat_build_inode);
 static void fat_delete_inode(struct inode *inode)
 {
 	truncate_inode_pages(&inode->i_data, 0);
-
-	if (!is_bad_inode(inode)) {
-		inode->i_size = 0;
-		fat_truncate(inode);
-	}
+	inode->i_size = 0;
+	fat_truncate(inode);
 	clear_inode(inode);
 }
 
@@ -445,8 +442,6 @@ static void fat_clear_inode(struct inode
 {
 	struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
 
-	if (is_bad_inode(inode))
-		return;
 	lock_kernel();
 	spin_lock(&sbi->inode_hash_lock);
 	fat_cache_inval_inode(inode);
_

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 2/9] fat: fat_notify_change() and check_mode() cleanup
  2008-04-20 18:13 [PATCH 1/9] fat: kill is_bad_inode() check OGAWA Hirofumi
@ 2008-04-20 18:13 ` OGAWA Hirofumi
  2008-04-20 18:13   ` [PATCH 3/9] fat: fat_setattr() fix OGAWA Hirofumi
  0 siblings, 1 reply; 9+ messages in thread
From: OGAWA Hirofumi @ 2008-04-20 18:13 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, hirofumi


- Rename fat_notify_change() to fat_setattr()
- check_mode() cleanup
- Change layout of code

Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
---

 fs/fat/file.c            |  183 +++++++++++++++++++++-------------------------
 fs/msdos/namei.c         |    2 
 fs/vfat/namei.c          |    2 
 include/linux/msdos_fs.h |    2 
 4 files changed, 87 insertions(+), 102 deletions(-)

diff -puN fs/fat/file.c~fat_notify_change-cleanup fs/fat/file.c
--- linux-2.6/fs/fat/file.c~fat_notify_change-cleanup	2008-02-15 19:09:45.000000000 +0900
+++ linux-2.6-hirofumi/fs/fat/file.c	2008-02-15 19:31:52.000000000 +0900
@@ -155,104 +155,6 @@ out:
 	return err;
 }
 
-static int check_mode(const struct msdos_sb_info *sbi, mode_t mode)
-{
-	mode_t req = mode & ~S_IFMT;
-
-	/*
-	 * Of the r and x bits, all (subject to umask) must be present. Of the
-	 * w bits, either all (subject to umask) or none must be present.
-	 */
-
-	if (S_ISREG(mode)) {
-		req &= ~sbi->options.fs_fmask;
-
-		if ((req & (S_IRUGO | S_IXUGO)) !=
-		    ((S_IRUGO | S_IXUGO) & ~sbi->options.fs_fmask))
-			return -EPERM;
-
-		if ((req & S_IWUGO) != 0 &&
-		    (req & S_IWUGO) != (S_IWUGO & ~sbi->options.fs_fmask))
-			return -EPERM;
-	} else if (S_ISDIR(mode)) {
-		req &= ~sbi->options.fs_dmask;
-
-		if ((req & (S_IRUGO | S_IXUGO)) !=
-		    ((S_IRUGO | S_IXUGO) & ~sbi->options.fs_dmask))
-			return -EPERM;
-
-		if ((req & S_IWUGO) != 0 &&
-		    (req & S_IWUGO) != (S_IWUGO & ~sbi->options.fs_dmask))
-			return -EPERM;
-	} else {
-		return -EPERM;
-	}
-
-	return 0;
-}
-
-int fat_notify_change(struct dentry *dentry, struct iattr *attr)
-{
-	struct msdos_sb_info *sbi = MSDOS_SB(dentry->d_sb);
-	struct inode *inode = dentry->d_inode;
-	int mask, error = 0;
-
-	lock_kernel();
-
-	/*
-	 * Expand the file. Since inode_setattr() updates ->i_size
-	 * before calling the ->truncate(), but FAT needs to fill the
-	 * hole before it.
-	 */
-	if (attr->ia_valid & ATTR_SIZE) {
-		if (attr->ia_size > inode->i_size) {
-			error = fat_cont_expand(inode, attr->ia_size);
-			if (error || attr->ia_valid == ATTR_SIZE)
-				goto out;
-			attr->ia_valid &= ~ATTR_SIZE;
-		}
-	}
-
-	error = inode_change_ok(inode, attr);
-	if (error) {
-		if (sbi->options.quiet)
-			error = 0;
-		goto out;
-	}
-	if (((attr->ia_valid & ATTR_UID) &&
-	     (attr->ia_uid != sbi->options.fs_uid)) ||
-	    ((attr->ia_valid & ATTR_GID) &&
-	     (attr->ia_gid != sbi->options.fs_gid)))
-		error = -EPERM;
-
-	if (error) {
-		if (sbi->options.quiet)
-			error = 0;
-		goto out;
-	}
-
-	if (attr->ia_valid & ATTR_MODE) {
-		error = check_mode(sbi, attr->ia_mode);
-		if (error != 0 && !sbi->options.quiet)
-			goto out;
-	}
-
-	error = inode_setattr(inode, attr);
-	if (error)
-		goto out;
-
-	if (S_ISDIR(inode->i_mode))
-		mask = sbi->options.fs_dmask;
-	else
-		mask = sbi->options.fs_fmask;
-	inode->i_mode &= S_IFMT | (S_IRWXUGO & ~mask);
-out:
-	unlock_kernel();
-	return error;
-}
-
-EXPORT_SYMBOL_GPL(fat_notify_change);
-
 /* Free all clusters after the skip'th cluster. */
 static int fat_free(struct inode *inode, int skip)
 {
@@ -353,8 +255,91 @@ int fat_getattr(struct vfsmount *mnt, st
 }
 EXPORT_SYMBOL_GPL(fat_getattr);
 
+static int fat_check_mode(const struct msdos_sb_info *sbi, mode_t mode)
+{
+	mode_t mask, req = mode & ~S_IFMT;
+
+	if (S_ISREG(mode))
+		mask = sbi->options.fs_fmask;
+	else
+		mask = sbi->options.fs_dmask;
+
+	/*
+	 * Of the r and x bits, all (subject to umask) must be present. Of the
+	 * w bits, either all (subject to umask) or none must be present.
+	 */
+	req &= ~mask;
+	if ((req & (S_IRUGO | S_IXUGO)) != ((S_IRUGO | S_IXUGO) & ~mask))
+		return -EPERM;
+	if ((req & S_IWUGO) && ((req & S_IWUGO) != (S_IWUGO & ~mask)))
+		return -EPERM;
+
+	return 0;
+}
+
+int fat_setattr(struct dentry *dentry, struct iattr *attr)
+{
+	struct msdos_sb_info *sbi = MSDOS_SB(dentry->d_sb);
+	struct inode *inode = dentry->d_inode;
+	int mask, error = 0;
+
+	lock_kernel();
+
+	/*
+	 * Expand the file. Since inode_setattr() updates ->i_size
+	 * before calling the ->truncate(), but FAT needs to fill the
+	 * hole before it.
+	 */
+	if (attr->ia_valid & ATTR_SIZE) {
+		if (attr->ia_size > inode->i_size) {
+			error = fat_cont_expand(inode, attr->ia_size);
+			if (error || attr->ia_valid == ATTR_SIZE)
+				goto out;
+			attr->ia_valid &= ~ATTR_SIZE;
+		}
+	}
+
+	error = inode_change_ok(inode, attr);
+	if (error) {
+		if (sbi->options.quiet)
+			error = 0;
+		goto out;
+	}
+	if (((attr->ia_valid & ATTR_UID) &&
+	     (attr->ia_uid != sbi->options.fs_uid)) ||
+	    ((attr->ia_valid & ATTR_GID) &&
+	     (attr->ia_gid != sbi->options.fs_gid)))
+		error = -EPERM;
+
+	if (error) {
+		if (sbi->options.quiet)
+			error = 0;
+		goto out;
+	}
+
+	if (attr->ia_valid & ATTR_MODE) {
+		error = fat_check_mode(sbi, attr->ia_mode);
+		if (error != 0 && !sbi->options.quiet)
+			goto out;
+	}
+
+	error = inode_setattr(inode, attr);
+	if (error)
+		goto out;
+
+	if (S_ISDIR(inode->i_mode))
+		mask = sbi->options.fs_dmask;
+	else
+		mask = sbi->options.fs_fmask;
+	inode->i_mode &= S_IFMT | (S_IRWXUGO & ~mask);
+out:
+	unlock_kernel();
+	return error;
+}
+EXPORT_SYMBOL_GPL(fat_setattr);
+
 const struct inode_operations fat_file_inode_operations = {
 	.truncate	= fat_truncate,
-	.setattr	= fat_notify_change,
+	.setattr	= fat_setattr,
 	.getattr	= fat_getattr,
 };
diff -puN fs/msdos/namei.c~fat_notify_change-cleanup fs/msdos/namei.c
--- linux-2.6/fs/msdos/namei.c~fat_notify_change-cleanup	2008-02-15 19:13:05.000000000 +0900
+++ linux-2.6-hirofumi/fs/msdos/namei.c	2008-02-15 19:13:09.000000000 +0900
@@ -653,7 +653,7 @@ static const struct inode_operations msd
 	.mkdir		= msdos_mkdir,
 	.rmdir		= msdos_rmdir,
 	.rename		= msdos_rename,
-	.setattr	= fat_notify_change,
+	.setattr	= fat_setattr,
 	.getattr	= fat_getattr,
 };
 
diff -puN fs/vfat/namei.c~fat_notify_change-cleanup fs/vfat/namei.c
--- linux-2.6/fs/vfat/namei.c~fat_notify_change-cleanup	2008-02-15 19:13:18.000000000 +0900
+++ linux-2.6-hirofumi/fs/vfat/namei.c	2008-02-15 19:13:23.000000000 +0900
@@ -1003,7 +1003,7 @@ static const struct inode_operations vfa
 	.mkdir		= vfat_mkdir,
 	.rmdir		= vfat_rmdir,
 	.rename		= vfat_rename,
-	.setattr	= fat_notify_change,
+	.setattr	= fat_setattr,
 	.getattr	= fat_getattr,
 };
 
diff -puN include/linux/msdos_fs.h~fat_notify_change-cleanup include/linux/msdos_fs.h
--- linux-2.6/include/linux/msdos_fs.h~fat_notify_change-cleanup	2008-02-15 19:13:32.000000000 +0900
+++ linux-2.6-hirofumi/include/linux/msdos_fs.h	2008-02-15 19:13:37.000000000 +0900
@@ -401,7 +401,7 @@ extern int fat_generic_ioctl(struct inod
 			     unsigned int cmd, unsigned long arg);
 extern const struct file_operations fat_file_operations;
 extern const struct inode_operations fat_file_inode_operations;
-extern int fat_notify_change(struct dentry * dentry, struct iattr * attr);
+extern int fat_setattr(struct dentry * dentry, struct iattr * attr);
 extern void fat_truncate(struct inode *inode);
 extern int fat_getattr(struct vfsmount *mnt, struct dentry *dentry,
 		       struct kstat *stat);
_

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 3/9] fat: fat_setattr() fix
  2008-04-20 18:13 ` [PATCH 2/9] fat: fat_notify_change() and check_mode() cleanup OGAWA Hirofumi
@ 2008-04-20 18:13   ` OGAWA Hirofumi
  2008-04-20 18:13     ` [PATCH 4/9] fat: Add allow_utime option OGAWA Hirofumi
  0 siblings, 1 reply; 9+ messages in thread
From: OGAWA Hirofumi @ 2008-04-20 18:13 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, hirofumi



Fix fat_setattr() on the case of showexec option. If user specified
showexec option, inode->i_mode may not have S_IXUGO. This just use
inode->i_mode to fix it.

And with this patch, we don't allow chmod() on memory inode, it's just
bad behaviour. IOW, we allow changing S_IWUGO only which can be stored
to disk.

Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
---

 fs/fat/file.c |   15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)

diff -puN fs/fat/file.c~fat_setattr-fix fs/fat/file.c
--- linux-2.6/fs/fat/file.c~fat_setattr-fix	2008-02-20 15:28:06.000000000 +0900
+++ linux-2.6-hirofumi/fs/fat/file.c	2008-02-21 11:42:25.000000000 +0900
@@ -255,7 +255,8 @@ int fat_getattr(struct vfsmount *mnt, st
 }
 EXPORT_SYMBOL_GPL(fat_getattr);
 
-static int fat_check_mode(const struct msdos_sb_info *sbi, mode_t mode)
+static int fat_check_mode(const struct msdos_sb_info *sbi, struct inode *inode,
+			  mode_t mode)
 {
 	mode_t mask, req = mode & ~S_IFMT;
 
@@ -269,7 +270,7 @@ static int fat_check_mode(const struct m
 	 * w bits, either all (subject to umask) or none must be present.
 	 */
 	req &= ~mask;
-	if ((req & (S_IRUGO | S_IXUGO)) != ((S_IRUGO | S_IXUGO) & ~mask))
+	if ((req & (S_IRUGO | S_IXUGO)) != (inode->i_mode & (S_IRUGO|S_IXUGO)))
 		return -EPERM;
 	if ((req & S_IWUGO) && ((req & S_IWUGO) != (S_IWUGO & ~mask)))
 		return -EPERM;
@@ -308,7 +309,9 @@ int fat_setattr(struct dentry *dentry, s
 	if (((attr->ia_valid & ATTR_UID) &&
 	     (attr->ia_uid != sbi->options.fs_uid)) ||
 	    ((attr->ia_valid & ATTR_GID) &&
-	     (attr->ia_gid != sbi->options.fs_gid)))
+	     (attr->ia_gid != sbi->options.fs_gid)) ||
+	    ((attr->ia_valid & ATTR_MODE) &&
+	     fat_check_mode(sbi, inode, attr->ia_mode) < 0))
 		error = -EPERM;
 
 	if (error) {
@@ -317,12 +320,6 @@ int fat_setattr(struct dentry *dentry, s
 		goto out;
 	}
 
-	if (attr->ia_valid & ATTR_MODE) {
-		error = fat_check_mode(sbi, attr->ia_mode);
-		if (error != 0 && !sbi->options.quiet)
-			goto out;
-	}
-
 	error = inode_setattr(inode, attr);
 	if (error)
 		goto out;
_

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 4/9] fat: Add allow_utime option
  2008-04-20 18:13   ` [PATCH 3/9] fat: fat_setattr() fix OGAWA Hirofumi
@ 2008-04-20 18:13     ` OGAWA Hirofumi
  2008-04-20 18:13       ` [PATCH 5/9] fat: Update free_clusters even if it is untrusted OGAWA Hirofumi
  0 siblings, 1 reply; 9+ messages in thread
From: OGAWA Hirofumi @ 2008-04-20 18:13 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, hirofumi


Normally utime(2) checks current process is owner of the file, or it
has CAP_FOWNER capability.  But FAT filesystem doesn't have uid/gid as
on disk info, so normal check is too unflexible.

With this option you can relax it.

Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
---

 Documentation/filesystems/vfat.txt |   15 +++++++++++++++
 fs/fat/file.c                      |   24 ++++++++++++++++++++++++
 fs/fat/inode.c                     |   18 +++++++++++++++---
 include/linux/msdos_fs.h           |    1 +
 4 files changed, 55 insertions(+), 3 deletions(-)

diff -puN fs/fat/file.c~fat_allow_utime fs/fat/file.c
--- linux-2.6/fs/fat/file.c~fat_allow_utime	2008-03-14 05:02:22.000000000 +0900
+++ linux-2.6-hirofumi/fs/fat/file.c	2008-03-14 05:36:19.000000000 +0900
@@ -278,11 +278,27 @@ static int fat_check_mode(const struct m
 	return 0;
 }
 
+static int fat_allow_set_time(struct msdos_sb_info *sbi, struct inode *inode)
+{
+	mode_t allow_utime = sbi->options.allow_utime;
+
+	if (current->fsuid != inode->i_uid) {
+		if (in_group_p(inode->i_gid))
+			allow_utime >>= 3;
+		if (allow_utime & MAY_WRITE)
+			return 1;
+	}
+
+	/* use a default check */
+	return 0;
+}
+
 int fat_setattr(struct dentry *dentry, struct iattr *attr)
 {
 	struct msdos_sb_info *sbi = MSDOS_SB(dentry->d_sb);
 	struct inode *inode = dentry->d_inode;
 	int mask, error = 0;
+	unsigned int ia_valid;
 
 	lock_kernel();
 
@@ -300,7 +316,15 @@ int fat_setattr(struct dentry *dentry, s
 		}
 	}
 
+	/* Check for setting the inode time. */
+	ia_valid = attr->ia_valid;
+	if (ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET)) {
+		if (fat_allow_set_time(sbi, inode))
+			attr->ia_valid &= ~(ATTR_MTIME_SET | ATTR_ATIME_SET);
+	}
+
 	error = inode_change_ok(inode, attr);
+	attr->ia_valid = ia_valid;
 	if (error) {
 		if (sbi->options.quiet)
 			error = 0;
diff -puN fs/fat/inode.c~fat_allow_utime fs/fat/inode.c
--- linux-2.6/fs/fat/inode.c~fat_allow_utime	2008-03-14 05:02:22.000000000 +0900
+++ linux-2.6-hirofumi/fs/fat/inode.c	2008-03-14 05:35:37.000000000 +0900
@@ -785,6 +785,8 @@ static int fat_show_options(struct seq_f
 		seq_printf(m, ",gid=%u", opts->fs_gid);
 	seq_printf(m, ",fmask=%04o", opts->fs_fmask);
 	seq_printf(m, ",dmask=%04o", opts->fs_dmask);
+	if (opts->allow_utime)
+		seq_printf(m, ",allow_utime=%04o", opts->allow_utime);
 	if (sbi->nls_disk)
 		seq_printf(m, ",codepage=%s", sbi->nls_disk->charset);
 	if (isvfat) {
@@ -840,9 +842,9 @@ static int fat_show_options(struct seq_f
 
 enum {
 	Opt_check_n, Opt_check_r, Opt_check_s, Opt_uid, Opt_gid,
-	Opt_umask, Opt_dmask, Opt_fmask, Opt_codepage, Opt_usefree, Opt_nocase,
-	Opt_quiet, Opt_showexec, Opt_debug, Opt_immutable,
-	Opt_dots, Opt_nodots,
+	Opt_umask, Opt_dmask, Opt_fmask, Opt_allow_utime, Opt_codepage,
+	Opt_usefree, Opt_nocase, Opt_quiet, Opt_showexec, Opt_debug,
+	Opt_immutable, Opt_dots, Opt_nodots,
 	Opt_charset, Opt_shortname_lower, Opt_shortname_win95,
 	Opt_shortname_winnt, Opt_shortname_mixed, Opt_utf8_no, Opt_utf8_yes,
 	Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes,
@@ -861,6 +863,7 @@ static match_table_t fat_tokens = {
 	{Opt_umask, "umask=%o"},
 	{Opt_dmask, "dmask=%o"},
 	{Opt_fmask, "fmask=%o"},
+	{Opt_allow_utime, "allow_utime=%o"},
 	{Opt_codepage, "codepage=%u"},
 	{Opt_usefree, "usefree"},
 	{Opt_nocase, "nocase"},
@@ -932,6 +935,7 @@ static int parse_options(char *options, 
 	opts->fs_uid = current->uid;
 	opts->fs_gid = current->gid;
 	opts->fs_fmask = opts->fs_dmask = current->fs->umask;
+	opts->allow_utime = -1;
 	opts->codepage = fat_default_codepage;
 	opts->iocharset = fat_default_iocharset;
 	if (is_vfat)
@@ -1019,6 +1023,11 @@ static int parse_options(char *options, 
 				return 0;
 			opts->fs_fmask = option;
 			break;
+		case Opt_allow_utime:
+			if (match_octal(&args[0], &option))
+				return 0;
+			opts->allow_utime = option & (S_IWGRP | S_IWOTH);
+			break;
 		case Opt_codepage:
 			if (match_int(&args[0], &option))
 				return 0;
@@ -1101,6 +1110,9 @@ static int parse_options(char *options, 
 		       " for FAT filesystems, filesystem will be case sensitive!\n");
 	}
 
+	/* If user doesn't specify allow_utime, it's initialized from dmask. */
+	if (opts->allow_utime == (unsigned short)-1)
+		opts->allow_utime = ~opts->fs_dmask & (S_IWGRP | S_IWOTH);
 	if (opts->unicode_xlate)
 		opts->utf8 = 0;
 
diff -puN include/linux/msdos_fs.h~fat_allow_utime include/linux/msdos_fs.h
--- linux-2.6/include/linux/msdos_fs.h~fat_allow_utime	2008-03-14 05:02:22.000000000 +0900
+++ linux-2.6-hirofumi/include/linux/msdos_fs.h	2008-03-14 05:35:37.000000000 +0900
@@ -195,6 +195,7 @@ struct fat_mount_options {
 	char *iocharset;          /* Charset used for filename input/display */
 	unsigned short shortname; /* flags for shortname display/create rule */
 	unsigned char name_check; /* r = relaxed, n = normal, s = strict */
+	unsigned short allow_utime;/* permission for setting the [am]time */
 	unsigned quiet:1,         /* set = fake successful chmods and chowns */
 		 showexec:1,      /* set = only set x bit for com/exe/bat */
 		 sys_immutable:1, /* set = system files are immutable */
diff -puN Documentation/filesystems/vfat.txt~fat_allow_utime Documentation/filesystems/vfat.txt
--- linux-2.6/Documentation/filesystems/vfat.txt~fat_allow_utime	2008-03-14 05:02:22.000000000 +0900
+++ linux-2.6-hirofumi/Documentation/filesystems/vfat.txt	2008-03-14 05:02:22.000000000 +0900
@@ -17,6 +17,21 @@ dmask=###     -- The permission mask for
 fmask=###     -- The permission mask for files.
                  The default is the umask of current process.
 
+allow_utime=### -- This option controls the permission check of mtime/atime.
+
+                  20 - If current process is in group of file's group ID,
+                       you can change timestamp.
+                   2 - Other users can change timestamp.
+
+                 The default is set from `dmask' option. (If the directory is
+                 writable, utime(2) is also allowed. I.e. ~dmask & 022)
+
+                 Normally utime(2) checks current process is owner of
+                 the file, or it has CAP_FOWNER capability.  But FAT
+                 filesystem doesn't have uid/gid on disk, so normal
+                 check is too unflexible. With this option you can
+                 relax it.
+
 codepage=###  -- Sets the codepage number for converting to shortname
 		 characters on FAT filesystem.
 		 By default, FAT_DEFAULT_CODEPAGE setting is used.
_

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 6/9] fat: Remove fat_clusters_flush()
  2008-04-20 18:13       ` [PATCH 5/9] fat: Update free_clusters even if it is untrusted OGAWA Hirofumi
@ 2008-04-20 18:13         ` OGAWA Hirofumi
  2008-04-20 18:13           ` [PATCH 7/9] Add balance_dirty_pages_ratelimited() to cont_expand_zero() OGAWA Hirofumi
  0 siblings, 1 reply; 9+ messages in thread
From: OGAWA Hirofumi @ 2008-04-20 18:13 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, hirofumi


This removes unneeded fat_clusters_flush().

Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
---

 fs/fat/fatent.c |    2 --
 1 file changed, 2 deletions(-)

diff -puN fs/fat/fatent.c~fat-remove-fat_clusters_flush fs/fat/fatent.c
--- linux-2.6/fs/fat/fatent.c~fat-remove-fat_clusters_flush	2008-04-19 11:55:07.000000000 +0900
+++ linux-2.6-hirofumi/fs/fat/fatent.c	2008-04-19 11:55:07.000000000 +0900
@@ -585,8 +585,6 @@ error:
 		brelse(bhs[i]);
 	unlock_fat(sbi);
 
-	fat_clusters_flush(sb);
-
 	return err;
 }
 
_

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 5/9] fat: Update free_clusters even if it is untrusted
  2008-04-20 18:13     ` [PATCH 4/9] fat: Add allow_utime option OGAWA Hirofumi
@ 2008-04-20 18:13       ` OGAWA Hirofumi
  2008-04-20 18:13         ` [PATCH 6/9] fat: Remove fat_clusters_flush() OGAWA Hirofumi
  0 siblings, 1 reply; 9+ messages in thread
From: OGAWA Hirofumi @ 2008-04-20 18:13 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, hirofumi


Currently, free_clusters is not updated until it is trusted, because
Windows doesn't update it correctly.

But if user is using FAT driver of Linux, it updates free_clusters
correctly.  Instead, this updates it even if it's untrusted, so if
free_clustes is correct, now keep correct value.

Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
---

 fs/fat/fatent.c          |    7 +++++--
 fs/fat/inode.c           |    7 ++++---
 include/linux/msdos_fs.h |    1 +
 3 files changed, 10 insertions(+), 5 deletions(-)

diff -puN include/linux/msdos_fs.h~fat_fix-free_clusters-check include/linux/msdos_fs.h
--- linux-2.6/include/linux/msdos_fs.h~fat_fix-free_clusters-check	2008-03-14 05:38:40.000000000 +0900
+++ linux-2.6-hirofumi/include/linux/msdos_fs.h	2008-03-14 05:38:40.000000000 +0900
@@ -233,6 +233,7 @@ struct msdos_sb_info {
 	struct mutex fat_lock;
 	unsigned int prev_free;      /* previously allocated cluster number */
 	unsigned int free_clusters;  /* -1 if undefined */
+	unsigned int free_clus_valid; /* is free_clusters valid? */
 	struct fat_mount_options options;
 	struct nls_table *nls_disk;  /* Codepage used on disk */
 	struct nls_table *nls_io;    /* Charset used for input and display */
diff -puN fs/fat/inode.c~fat_fix-free_clusters-check fs/fat/inode.c
--- linux-2.6/fs/fat/inode.c~fat_fix-free_clusters-check	2008-03-14 05:38:40.000000000 +0900
+++ linux-2.6-hirofumi/fs/fat/inode.c	2008-03-14 05:38:40.000000000 +0900
@@ -537,7 +537,7 @@ static int fat_statfs(struct dentry *den
 	struct msdos_sb_info *sbi = MSDOS_SB(dentry->d_sb);
 
 	/* If the count of free cluster is still unknown, counts it here. */
-	if (sbi->free_clusters == -1) {
+	if (sbi->free_clusters == -1 || !sbi->free_clus_valid) {
 		int err = fat_count_free_clusters(dentry->d_sb);
 		if (err)
 			return err;
@@ -1274,6 +1274,7 @@ int fat_fill_super(struct super_block *s
 	sbi->fat_length = le16_to_cpu(b->fat_length);
 	sbi->root_cluster = 0;
 	sbi->free_clusters = -1;	/* Don't know yet */
+	sbi->free_clus_valid = 0;
 	sbi->prev_free = FAT_START_ENT;
 
 	if (!sbi->fat_length && b->fat32_length) {
@@ -1309,8 +1310,8 @@ int fat_fill_super(struct super_block *s
 			       sbi->fsinfo_sector);
 		} else {
 			if (sbi->options.usefree)
-				sbi->free_clusters =
-					le32_to_cpu(fsinfo->free_clusters);
+				sbi->free_clus_valid = 1;
+			sbi->free_clusters = le32_to_cpu(fsinfo->free_clusters);
 			sbi->prev_free = le32_to_cpu(fsinfo->next_cluster);
 		}
 
diff -puN fs/fat/fatent.c~fat_fix-free_clusters-check fs/fat/fatent.c
--- linux-2.6/fs/fat/fatent.c~fat_fix-free_clusters-check	2008-03-14 05:38:40.000000000 +0900
+++ linux-2.6-hirofumi/fs/fat/fatent.c	2008-03-14 05:38:40.000000000 +0900
@@ -450,7 +450,8 @@ int fat_alloc_clusters(struct inode *ino
 	BUG_ON(nr_cluster > (MAX_BUF_PER_PAGE / 2));	/* fixed limit */
 
 	lock_fat(sbi);
-	if (sbi->free_clusters != -1 && sbi->free_clusters < nr_cluster) {
+	if (sbi->free_clusters != -1 && sbi->free_clus_valid &&
+	    sbi->free_clusters < nr_cluster) {
 		unlock_fat(sbi);
 		return -ENOSPC;
 	}
@@ -504,6 +505,7 @@ int fat_alloc_clusters(struct inode *ino
 
 	/* Couldn't allocate the free entries */
 	sbi->free_clusters = 0;
+	sbi->free_clus_valid = 1;
 	sb->s_dirt = 1;
 	err = -ENOSPC;
 
@@ -615,7 +617,7 @@ int fat_count_free_clusters(struct super
 	int err = 0, free;
 
 	lock_fat(sbi);
-	if (sbi->free_clusters != -1)
+	if (sbi->free_clusters != -1 && sbi->free_clus_valid)
 		goto out;
 
 	reada_blocks = FAT_READA_SIZE >> sb->s_blocksize_bits;
@@ -643,6 +645,7 @@ int fat_count_free_clusters(struct super
 		} while (fat_ent_next(sbi, &fatent));
 	}
 	sbi->free_clusters = free;
+	sbi->free_clus_valid = 1;
 	sb->s_dirt = 1;
 	fatent_brelse(&fatent);
 out:
_

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 7/9] Add balance_dirty_pages_ratelimited() to cont_expand_zero()
  2008-04-20 18:13         ` [PATCH 6/9] fat: Remove fat_clusters_flush() OGAWA Hirofumi
@ 2008-04-20 18:13           ` OGAWA Hirofumi
  2008-04-20 18:13             ` [PATCH 8/9] vfat: bug fix for vfat cannot handle filename with 255 OGAWA Hirofumi
  0 siblings, 1 reply; 9+ messages in thread
From: OGAWA Hirofumi @ 2008-04-20 18:13 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, hirofumi


On the systems, ftruncate() which expand size for FAT became the cause
of OOM.  The cont_expand_zero() filled all memory with dirty pages,
and since disk is very slow, limit of page scanning was exceeded, then
it triggered OOM.

This adds balance_dirty_pages_ratelimited() to avoid filling memory
with dirty pages.

Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
---

 fs/buffer.c |    2 ++
 1 file changed, 2 insertions(+)

diff -puN fs/buffer.c~cont_expand_zero-fix fs/buffer.c
--- linux-2.6/fs/buffer.c~cont_expand_zero-fix	2008-04-05 18:22:57.000000000 +0900
+++ linux-2.6-hirofumi/fs/buffer.c	2008-04-05 18:22:57.000000000 +0900
@@ -2251,6 +2251,8 @@ int cont_expand_zero(struct file *file, 
 			goto out;
 		BUG_ON(err != len);
 		err = 0;
+
+		balance_dirty_pages_ratelimited(mapping);
 	}
 
 	/* page covers the boundary, find the boundary offset */
_

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 8/9] vfat: bug fix for vfat cannot handle filename with 255
  2008-04-20 18:13           ` [PATCH 7/9] Add balance_dirty_pages_ratelimited() to cont_expand_zero() OGAWA Hirofumi
@ 2008-04-20 18:13             ` OGAWA Hirofumi
  2008-04-20 18:13               ` [PATCH 9/9] fat: use __getname() OGAWA Hirofumi
  0 siblings, 1 reply; 9+ messages in thread
From: OGAWA Hirofumi @ 2008-04-20 18:13 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, hirofumi, ek9852


From: Keith Mok <ek9852@gmail.com>

This patch fix the problem that the buffer allocated for convert of
unicode to utf8 in fat/dir.c is too small.
And cannot handle filename with 255 asian characters when mounted with
utf8 options.

Also it fix the filename length limitation checking in vfat/namei.c that
the filename length should be checked against the number of converted
unicode characters.
Not the length before NLS/UTF8 converted.

Signed-off-by: Keith Mok <ek9852@gmail.com>
Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
---

 fs/fat/dir.c    |   44 ++++++++++++++++++++++++++++----------------
 fs/vfat/namei.c |   25 +++++++++++--------------
 2 files changed, 39 insertions(+), 30 deletions(-)

diff -puN fs/fat/dir.c~fat_vfat-fix-filename-handing fs/fat/dir.c
--- linux-2.6/fs/fat/dir.c~fat_vfat-fix-filename-handing	2008-04-19 11:55:08.000000000 +0900
+++ linux-2.6-hirofumi/fs/fat/dir.c	2008-04-21 00:59:00.000000000 +0900
@@ -124,8 +124,8 @@ static inline int fat_get_entry(struct i
  * but ignore that right now.
  * Ahem... Stack smashing in ring 0 isn't fun. Fixed.
  */
-static int uni16_to_x8(unsigned char *ascii, wchar_t *uni, int uni_xlate,
-		       struct nls_table *nls)
+static int uni16_to_x8(unsigned char *ascii, wchar_t *uni, int len,
+		       int uni_xlate, struct nls_table *nls)
 {
 	wchar_t *ip, ec;
 	unsigned char *op, nc;
@@ -135,10 +135,11 @@ static int uni16_to_x8(unsigned char *as
 	ip = uni;
 	op = ascii;
 
-	while (*ip) {
+	while (*ip && ((len - NLS_MAX_CHARSET_SIZE) > 0)) {
 		ec = *ip++;
 		if ( (charlen = nls->uni2char(ec, op, NLS_MAX_CHARSET_SIZE)) > 0) {
 			op += charlen;
+			len -= charlen;
 		} else {
 			if (uni_xlate == 1) {
 				*op = ':';
@@ -149,16 +150,19 @@ static int uni16_to_x8(unsigned char *as
 					ec >>= 4;
 				}
 				op += 5;
+				len -= 5;
 			} else {
 				*op++ = '?';
+				len--;
 			}
 		}
-		/* We have some slack there, so it's OK */
-		if (op>ascii+256) {
-			op = ascii + 256;
-			break;
-		}
 	}
+
+	if (unlikely(*ip)) {
+		printk(KERN_WARNING "FAT: filename was truncated while "
+		       "converting.");
+	}
+
 	*op = 0;
 	return (op - ascii);
 }
@@ -311,9 +315,11 @@ int fat_search_long(struct inode *inode,
 	struct nls_table *nls_io = sbi->nls_io;
 	struct nls_table *nls_disk = sbi->nls_disk;
 	wchar_t bufuname[14];
-	unsigned char xlate_len, nr_slots;
+	unsigned char nr_slots;
+	int xlate_len;
 	wchar_t *unicode = NULL;
-	unsigned char work[MSDOS_NAME], bufname[260];	/* 256 + 4 */
+	unsigned char work[MSDOS_NAME];
+	unsigned char *bufname = NULL;
 	int uni_xlate = sbi->options.unicode_xlate;
 	int utf8 = sbi->options.utf8;
 	int anycase = (sbi->options.name_check != 's');
@@ -321,6 +327,10 @@ int fat_search_long(struct inode *inode,
 	loff_t cpos = 0;
 	int chl, i, j, last_u, err;
 
+	bufname = (unsigned char*)__get_free_page(GFP_KERNEL);
+	if (!bufname)
+		return -ENOMEM;
+
 	err = -ENOENT;
 	while(1) {
 		if (fat_get_entry(inode, &cpos, &bh, &de) == -1)
@@ -386,8 +396,8 @@ parse_record:
 
 		bufuname[last_u] = 0x0000;
 		xlate_len = utf8
-			?utf8_wcstombs(bufname, bufuname, sizeof(bufname))
-			:uni16_to_x8(bufname, bufuname, uni_xlate, nls_io);
+			?utf8_wcstombs(bufname, bufuname, PAGE_SIZE)
+			:uni16_to_x8(bufname, bufuname, PAGE_SIZE, uni_xlate, nls_io);
 		if (xlate_len == name_len)
 			if ((!anycase && !memcmp(name, bufname, xlate_len)) ||
 			    (anycase && !nls_strnicmp(nls_io, name, bufname,
@@ -396,8 +406,8 @@ parse_record:
 
 		if (nr_slots) {
 			xlate_len = utf8
-				?utf8_wcstombs(bufname, unicode, sizeof(bufname))
-				:uni16_to_x8(bufname, unicode, uni_xlate, nls_io);
+				?utf8_wcstombs(bufname, unicode, PAGE_SIZE)
+				:uni16_to_x8(bufname, unicode, PAGE_SIZE, uni_xlate, nls_io);
 			if (xlate_len != name_len)
 				continue;
 			if ((!anycase && !memcmp(name, bufname, xlate_len)) ||
@@ -416,6 +426,8 @@ Found:
 	sinfo->i_pos = fat_make_i_pos(sb, sinfo->bh, sinfo->de);
 	err = 0;
 EODir:
+	if (bufname)
+		free_page((unsigned long)bufname);
 	if (unicode)
 		free_page((unsigned long)unicode);
 
@@ -598,7 +610,7 @@ parse_record:
 	if (isvfat) {
 		bufuname[j] = 0x0000;
 		i = utf8 ? utf8_wcstombs(bufname, bufuname, sizeof(bufname))
-			 : uni16_to_x8(bufname, bufuname, uni_xlate, nls_io);
+			 : uni16_to_x8(bufname, bufuname, sizeof(bufname), uni_xlate, nls_io);
 	}
 
 	fill_name = bufname;
@@ -610,7 +622,7 @@ parse_record:
 		int buf_size = PAGE_SIZE - (261 * sizeof(unicode[0]));
 		int long_len = utf8
 			? utf8_wcstombs(longname, unicode, buf_size)
-			: uni16_to_x8(longname, unicode, uni_xlate, nls_io);
+			: uni16_to_x8(longname, unicode, buf_size, uni_xlate, nls_io);
 
 		if (!both) {
 			fill_name = longname;
diff -puN fs/vfat/namei.c~fat_vfat-fix-filename-handing fs/vfat/namei.c
--- linux-2.6/fs/vfat/namei.c~fat_vfat-fix-filename-handing	2008-04-19 11:55:08.000000000 +0900
+++ linux-2.6-hirofumi/fs/vfat/namei.c	2008-04-21 00:57:11.000000000 +0900
@@ -176,15 +176,10 @@ static inline int vfat_is_used_badchars(
 	for (i = 0; i < len; i++)
 		if (vfat_bad_char(s[i]))
 			return -EINVAL;
-	return 0;
-}
 
-static int vfat_valid_longname(const unsigned char *name, unsigned int len)
-{
-	if (name[len - 1] == ' ')
+	if (s[i - 1] == ' ') /* last character cannot be space */
 		return -EINVAL;
-	if (len >= 256)
-		return -ENAMETOOLONG;
+
 	return 0;
 }
 
@@ -485,11 +480,14 @@ xlate_to_uni(const unsigned char *name, 
 		 */
 		*outlen -= (name_len - len);
 
+		if (*outlen > 255)
+			return -ENAMETOOLONG;
+
 		op = &outname[*outlen * sizeof(wchar_t)];
 	} else {
 		if (nls) {
 			for (i = 0, ip = name, op = outname, *outlen = 0;
-			     i < len && *outlen <= 260;
+			     i < len && *outlen <= 255;
 			     *outlen += 1)
 			{
 				if (escape && (*ip == ':')) {
@@ -525,18 +523,20 @@ xlate_to_uni(const unsigned char *name, 
 					op += 2;
 				}
 			}
+			if (i < len)
+				return -ENAMETOOLONG;
 		} else {
 			for (i = 0, ip = name, op = outname, *outlen = 0;
-			     i < len && *outlen <= 260;
+			     i < len && *outlen <= 255;
 			     i++, *outlen += 1)
 			{
 				*op++ = *ip++;
 				*op++ = 0;
 			}
+			if (i < len)
+				return -ENAMETOOLONG;
 		}
 	}
-	if (*outlen > 260)
-		return -ENAMETOOLONG;
 
 	*longlen = *outlen;
 	if (*outlen % 13) {
@@ -574,9 +574,6 @@ static int vfat_build_slots(struct inode
 	loff_t offset;
 
 	*nr_slots = 0;
-	err = vfat_valid_longname(name, len);
-	if (err)
-		return err;
 
 	page = __get_free_page(GFP_KERNEL);
 	if (!page)
_

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 9/9] fat: use __getname()
  2008-04-20 18:13             ` [PATCH 8/9] vfat: bug fix for vfat cannot handle filename with 255 OGAWA Hirofumi
@ 2008-04-20 18:13               ` OGAWA Hirofumi
  0 siblings, 0 replies; 9+ messages in thread
From: OGAWA Hirofumi @ 2008-04-20 18:13 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, hirofumi


__getname() is faster than __get_free_page(). Use it.

Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
---

 fs/fat/dir.c    |   20 ++++++++++----------
 fs/vfat/namei.c |   10 ++++------
 2 files changed, 14 insertions(+), 16 deletions(-)

diff -puN fs/vfat/namei.c~fat_use-__getname fs/vfat/namei.c
--- linux-2.6/fs/vfat/namei.c~fat_use-__getname	2008-04-21 01:36:07.000000000 +0900
+++ linux-2.6-hirofumi/fs/vfat/namei.c	2008-04-21 01:36:07.000000000 +0900
@@ -472,7 +472,7 @@ xlate_to_uni(const unsigned char *name, 
 	if (utf8) {
 		int name_len = strlen(name);
 
-		*outlen = utf8_mbstowcs((wchar_t *)outname, name, PAGE_SIZE);
+		*outlen = utf8_mbstowcs((wchar_t *)outname, name, PATH_MAX);
 
 		/*
 		 * We stripped '.'s before and set len appropriately,
@@ -565,7 +565,6 @@ static int vfat_build_slots(struct inode
 	struct fat_mount_options *opts = &sbi->options;
 	struct msdos_dir_slot *ps;
 	struct msdos_dir_entry *de;
-	unsigned long page;
 	unsigned char cksum, lcase;
 	unsigned char msdos_name[MSDOS_NAME];
 	wchar_t *uname;
@@ -575,11 +574,10 @@ static int vfat_build_slots(struct inode
 
 	*nr_slots = 0;
 
-	page = __get_free_page(GFP_KERNEL);
-	if (!page)
+	uname = __getname();
+	if (!uname)
 		return -ENOMEM;
 
-	uname = (wchar_t *)page;
 	err = xlate_to_uni(name, len, (unsigned char *)uname, &ulen, &usize,
 			   opts->unicode_xlate, opts->utf8, sbi->nls_io);
 	if (err)
@@ -631,7 +629,7 @@ shortname:
 	de->starthi = cpu_to_le16(cluster >> 16);
 	de->size = 0;
 out_free:
-	free_page(page);
+	__putname(uname);
 	return err;
 }
 
diff -puN fs/fat/dir.c~fat_use-__getname fs/fat/dir.c
--- linux-2.6/fs/fat/dir.c~fat_use-__getname	2008-04-21 01:36:07.000000000 +0900
+++ linux-2.6-hirofumi/fs/fat/dir.c	2008-04-21 01:36:07.000000000 +0900
@@ -247,7 +247,7 @@ static int fat_parse_long(struct inode *
 	unsigned char id, slot, slots, alias_checksum;
 
 	if (!*unicode) {
-		*unicode = (wchar_t *)__get_free_page(GFP_KERNEL);
+		*unicode = __getname();
 		if (!*unicode) {
 			brelse(*bh);
 			return -ENOMEM;
@@ -327,7 +327,7 @@ int fat_search_long(struct inode *inode,
 	loff_t cpos = 0;
 	int chl, i, j, last_u, err;
 
-	bufname = (unsigned char*)__get_free_page(GFP_KERNEL);
+	bufname = __getname();
 	if (!bufname)
 		return -ENOMEM;
 
@@ -396,8 +396,8 @@ parse_record:
 
 		bufuname[last_u] = 0x0000;
 		xlate_len = utf8
-			?utf8_wcstombs(bufname, bufuname, PAGE_SIZE)
-			:uni16_to_x8(bufname, bufuname, PAGE_SIZE, uni_xlate, nls_io);
+			?utf8_wcstombs(bufname, bufuname, PATH_MAX)
+			:uni16_to_x8(bufname, bufuname, PATH_MAX, uni_xlate, nls_io);
 		if (xlate_len == name_len)
 			if ((!anycase && !memcmp(name, bufname, xlate_len)) ||
 			    (anycase && !nls_strnicmp(nls_io, name, bufname,
@@ -406,8 +406,8 @@ parse_record:
 
 		if (nr_slots) {
 			xlate_len = utf8
-				?utf8_wcstombs(bufname, unicode, PAGE_SIZE)
-				:uni16_to_x8(bufname, unicode, PAGE_SIZE, uni_xlate, nls_io);
+				?utf8_wcstombs(bufname, unicode, PATH_MAX)
+				:uni16_to_x8(bufname, unicode, PATH_MAX, uni_xlate, nls_io);
 			if (xlate_len != name_len)
 				continue;
 			if ((!anycase && !memcmp(name, bufname, xlate_len)) ||
@@ -427,9 +427,9 @@ Found:
 	err = 0;
 EODir:
 	if (bufname)
-		free_page((unsigned long)bufname);
+		__putname(bufname);
 	if (unicode)
-		free_page((unsigned long)unicode);
+		__putname(unicode);
 
 	return err;
 }
@@ -619,7 +619,7 @@ parse_record:
 		/* convert the unicode long name. 261 is maximum size
 		 * of unicode buffer. (13 * slots + nul) */
 		void *longname = unicode + 261;
-		int buf_size = PAGE_SIZE - (261 * sizeof(unicode[0]));
+		int buf_size = PATH_MAX - (261 * sizeof(unicode[0]));
 		int long_len = utf8
 			? utf8_wcstombs(longname, unicode, buf_size)
 			: uni16_to_x8(longname, unicode, buf_size, uni_xlate, nls_io);
@@ -652,7 +652,7 @@ EODir:
 FillFailed:
 	brelse(bh);
 	if (unicode)
-		free_page((unsigned long)unicode);
+		__putname(unicode);
 out:
 	unlock_kernel();
 	return ret;
_

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2008-04-20 18:29 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-04-20 18:13 [PATCH 1/9] fat: kill is_bad_inode() check OGAWA Hirofumi
2008-04-20 18:13 ` [PATCH 2/9] fat: fat_notify_change() and check_mode() cleanup OGAWA Hirofumi
2008-04-20 18:13   ` [PATCH 3/9] fat: fat_setattr() fix OGAWA Hirofumi
2008-04-20 18:13     ` [PATCH 4/9] fat: Add allow_utime option OGAWA Hirofumi
2008-04-20 18:13       ` [PATCH 5/9] fat: Update free_clusters even if it is untrusted OGAWA Hirofumi
2008-04-20 18:13         ` [PATCH 6/9] fat: Remove fat_clusters_flush() OGAWA Hirofumi
2008-04-20 18:13           ` [PATCH 7/9] Add balance_dirty_pages_ratelimited() to cont_expand_zero() OGAWA Hirofumi
2008-04-20 18:13             ` [PATCH 8/9] vfat: bug fix for vfat cannot handle filename with 255 OGAWA Hirofumi
2008-04-20 18:13               ` [PATCH 9/9] fat: use __getname() OGAWA Hirofumi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®