summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2008-05-05 13:42:12 +0200
committerGreg Kroah-Hartman <gregkh@suse.de>2008-05-09 21:40:46 -0700
commitd5d70ec0dca55f84071354c10fbb1162023fab0a (patch)
tree138716cf19822a1da1ee2fcefa827972c5d3a7da
parent980e8ec0c4ab54164725f1a71545c439a755e918 (diff)
reiserfs: Unpack tails on quota files
commit d5dee5c395062a55236318ac4eec1f4ebb9de6db upstream Quota files cannot have tails because quota_write and quota_read functions do not support them. So far when quota files did have tail, we just refused to turn quotas on it. Sadly this check has been wrong and so there are now plenty installations where quota files don't have NOTAIL flag set and so now after fixing the check, they suddently fail to turn quotas on. Since it's easy to unpack the tail from kernel, do this from reiserfs_quota_on() which solves the problem and is generally nicer to users anyway. Signed-off-by: Jan Kara <jack@suse.cz> Reported-by: <urhausen@urifabi.net> Cc: Jeff Mahoney <jeffm@suse.com> Cc: Chris Mason <chris.mason@oracle.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--fs/reiserfs/ioctl.c4
-rw-r--r--fs/reiserfs/super.c17
-rw-r--r--include/linux/reiserfs_fs.h1
3 files changed, 14 insertions, 8 deletions
diff --git a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c
index e0f0f098a523..9f877ab4728b 100644
--- a/fs/reiserfs/ioctl.c
+++ b/fs/reiserfs/ioctl.c
@@ -11,8 +11,6 @@
#include <linux/smp_lock.h>
#include <linux/compat.h>
-static int reiserfs_unpack(struct inode *inode, struct file *filp);
-
/*
** reiserfs_ioctl - handler for ioctl for inode
** supported commands:
@@ -140,7 +138,7 @@ int reiserfs_prepare_write(struct file *f, struct page *page,
** Function try to convert tail from direct item into indirect.
** It set up nopack attribute in the REISERFS_I(inode)->nopack
*/
-static int reiserfs_unpack(struct inode *inode, struct file *filp)
+int reiserfs_unpack(struct inode *inode, struct file *filp)
{
int retval = 0;
int index;
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index 393cc22c1717..3302259cd3ca 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -2019,6 +2019,7 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id,
{
int err;
struct nameidata nd;
+ struct inode *inode;
if (!(REISERFS_SB(sb)->s_mount_opt & (1 << REISERFS_QUOTA)))
return -EINVAL;
@@ -2030,12 +2031,18 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id,
path_put(&nd.path);
return -EXDEV;
}
+ inode = nd.path.dentry->d_inode;
/* We must not pack tails for quota files on reiserfs for quota IO to work */
- if (!(REISERFS_I(nd.path.dentry->d_inode)->i_flags & i_nopack_mask)) {
- reiserfs_warning(sb,
- "reiserfs: Quota file must have tail packing disabled.");
- path_put(&nd.path);
- return -EINVAL;
+ if (!(REISERFS_I(inode)->i_flags & i_nopack_mask)) {
+ err = reiserfs_unpack(inode, NULL);
+ if (err) {
+ reiserfs_warning(sb,
+ "reiserfs: Unpacking tail of quota file failed"
+ " (%d). Cannot turn on quotas.", err);
+ path_put(&nd.path);
+ return -EINVAL;
+ }
+ mark_inode_dirty(inode);
}
/* Not journalling quota? No more tests needed... */
if (!REISERFS_SB(sb)->s_qf_names[USRQUOTA] &&
diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h
index 8e7eff2cd0ab..4aacaeecb56f 100644
--- a/include/linux/reiserfs_fs.h
+++ b/include/linux/reiserfs_fs.h
@@ -2176,6 +2176,7 @@ int reiserfs_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
long reiserfs_compat_ioctl(struct file *filp,
unsigned int cmd, unsigned long arg);
+int reiserfs_unpack(struct inode *inode, struct file *filp);
/* ioctl's command */
#define REISERFS_IOC_UNPACK _IOW(0xCD,1,long)