From c79d967de3741ceb60c5bbbf1b6f97eab9a89838 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 19 May 2010 07:16:40 -0400 Subject: quota: move remount handling into the filesystem Currently do_remount_sb calls into the dquot code to tell it about going from rw to ro and ro to rw. Move this code into the filesystem to not depend on the dquot code in the VFS - note ocfs2 already ignores these calls and handles remount by itself. This gets rid of overloading the quotactl calls and allows to unify the VFS and XFS codepaths in that area later. Signed-off-by: Christoph Hellwig Signed-off-by: Jan Kara --- fs/ufs/super.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'fs/ufs/super.c') diff --git a/fs/ufs/super.c b/fs/ufs/super.c index 14743d935a9..be1f7b05bc2 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c @@ -1248,7 +1248,9 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) struct ufs_super_block_first * usb1; struct ufs_super_block_third * usb3; unsigned new_mount_opt, ufstype; + int enable_quota = 0; unsigned flags; + int err; lock_kernel(); lock_super(sb); @@ -1289,6 +1291,13 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) * fs was mouted as rw, remounting ro */ if (*mount_flags & MS_RDONLY) { + err = vfs_dq_off(sb, 1); + if (err < 0 && err != -ENOSYS) { + unlock_super(sb); + unlock_kernel(); + return -EBUSY; + } + ufs_put_super_internal(sb); usb1->fs_time = cpu_to_fs32(sb, get_seconds()); if ((flags & UFS_ST_MASK) == UFS_ST_SUN @@ -1327,11 +1336,14 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) return -EPERM; } sb->s_flags &= ~MS_RDONLY; + enable_quota = 1; #endif } UFS_SB(sb)->s_mount_opt = new_mount_opt; unlock_super(sb); unlock_kernel(); + if (enable_quota) + vfs_dq_quota_on_remount(sb); return 0; } -- cgit v1.2.3 From 0f0dd62fddcbd0f6830ed8ef3d3426ccc46b9250 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 19 May 2010 07:16:41 -0400 Subject: quota: kill the vfs_dq_off and vfs_dq_quota_on_remount wrappers Instead of having wrappers in the VFS namespace export the dquot_suspend and dquot_resume helpers directly. Also rename vfs_quota_disable to dquot_disable while we're at it. [Jan Kara: Moved dquot_suspend to quotaops.h and made it inline] Signed-off-by: Christoph Hellwig Signed-off-by: Jan Kara --- fs/ufs/super.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'fs/ufs/super.c') diff --git a/fs/ufs/super.c b/fs/ufs/super.c index be1f7b05bc2..495fdc1df7e 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c @@ -1291,11 +1291,11 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) * fs was mouted as rw, remounting ro */ if (*mount_flags & MS_RDONLY) { - err = vfs_dq_off(sb, 1); - if (err < 0 && err != -ENOSYS) { + err = dquot_suspend(sb, -1); + if (err < 0) { unlock_super(sb); unlock_kernel(); - return -EBUSY; + return err; } ufs_put_super_internal(sb); @@ -1343,7 +1343,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) unlock_super(sb); unlock_kernel(); if (enable_quota) - vfs_dq_quota_on_remount(sb); + dquot_resume(sb, -1); return 0; } -- cgit v1.2.3 From e0ccfd959cd8907bcb66cc2042e0f4fd7fcbff2b Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 19 May 2010 07:16:42 -0400 Subject: quota: move unmount handling into the filesystem Currently the VFS calls into the quotactl interface for unmounting filesystems. This means filesystems with their own quota handling can't easily distinguish between user-space originating quotaoff and an unount. Instead move the responsibily of the unmount handling into the filesystem to be consistent with all other dquot handling. Note that we do call dquot_disable a lot later now, e.g. after a sync_filesystem. But this is fine as the quota code does all its writes via blockdev's mapping and that is synced even later. Signed-off-by: Christoph Hellwig Signed-off-by: Jan Kara --- fs/ufs/super.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'fs/ufs/super.c') diff --git a/fs/ufs/super.c b/fs/ufs/super.c index 495fdc1df7e..d3977c7128e 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c @@ -1227,6 +1227,8 @@ static void ufs_put_super(struct super_block *sb) UFSD("ENTER\n"); + dquot_disable(sb, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED); + if (sb->s_dirt) ufs_write_super(sb); -- cgit v1.2.3 From 123e9caf1e85008ab7eb5f6cd58c44f9a5d73b2b Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 19 May 2010 07:16:44 -0400 Subject: quota: explicitly set ->dq_op and ->s_qcop Only set the quota operation vectors if the filesystem actually supports quota instead of doing it for all filesystems in alloc_super(). [Jan Kara: Export dquot_operations and vfs_quotactl_ops] Signed-off-by: Christoph Hellwig Signed-off-by: Jan Kara --- fs/ufs/super.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'fs/ufs/super.c') diff --git a/fs/ufs/super.c b/fs/ufs/super.c index d3977c7128e..60c989b7012 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c @@ -1045,7 +1045,11 @@ magic_found: */ sb->s_op = &ufs_super_ops; sb->s_export_op = &ufs_export_ops; - sb->dq_op = NULL; /***/ +#ifdef CONFIG_QUOTA + sb->s_qcop = &vfs_quotactl_ops; + sb->dq_op = NULL; /* &dquot_operations */ +#endif + sb->s_magic = fs32_to_cpu(sb, usb3->fs_magic); uspi->s_sblkno = fs32_to_cpu(sb, usb1->fs_sblkno); -- cgit v1.2.3 From 287a80958cf63fc5c68d5bf6e89a3669dd66234a Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 19 May 2010 07:16:45 -0400 Subject: quota: rename default quotactl methods to dquot_ Follow the dquot_* style used elsewhere in dquot.c. [Jan Kara: Fixed up missing conversion of ext2] Signed-off-by: Christoph Hellwig Signed-off-by: Jan Kara --- fs/ufs/super.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs/ufs/super.c') diff --git a/fs/ufs/super.c b/fs/ufs/super.c index 60c989b7012..2b08a8dd8ec 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c @@ -1046,7 +1046,7 @@ magic_found: sb->s_op = &ufs_super_ops; sb->s_export_op = &ufs_export_ops; #ifdef CONFIG_QUOTA - sb->s_qcop = &vfs_quotactl_ops; + sb->s_qcop = &dquot_quotactl_ops; sb->dq_op = NULL; /* &dquot_operations */ #endif -- cgit v1.2.3 From 8f45c33decf62e1aaaa9411aae8fef6a38f95845 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Thu, 20 May 2010 16:00:36 +0200 Subject: ufs: Remove dead quota code UFS quota is non-functional at least since 2.6.12 because dq_op was set to NULL. Since the filesystem exists mainly to allow cooperation with Solaris and quota format isn't standard, just remove the dead code. CC: Evgeniy Dushistov Signed-off-by: Jan Kara --- fs/ufs/super.c | 126 --------------------------------------------------------- 1 file changed, 126 deletions(-) (limited to 'fs/ufs/super.c') diff --git a/fs/ufs/super.c b/fs/ufs/super.c index 2b08a8dd8ec..3c9bbf23c2f 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c @@ -77,7 +77,6 @@ #include #include -#include #include #include #include @@ -1045,10 +1044,6 @@ magic_found: */ sb->s_op = &ufs_super_ops; sb->s_export_op = &ufs_export_ops; -#ifdef CONFIG_QUOTA - sb->s_qcop = &dquot_quotactl_ops; - sb->dq_op = NULL; /* &dquot_operations */ -#endif sb->s_magic = fs32_to_cpu(sb, usb3->fs_magic); @@ -1231,8 +1226,6 @@ static void ufs_put_super(struct super_block *sb) UFSD("ENTER\n"); - dquot_disable(sb, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED); - if (sb->s_dirt) ufs_write_super(sb); @@ -1254,9 +1247,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) struct ufs_super_block_first * usb1; struct ufs_super_block_third * usb3; unsigned new_mount_opt, ufstype; - int enable_quota = 0; unsigned flags; - int err; lock_kernel(); lock_super(sb); @@ -1297,13 +1288,6 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) * fs was mouted as rw, remounting ro */ if (*mount_flags & MS_RDONLY) { - err = dquot_suspend(sb, -1); - if (err < 0) { - unlock_super(sb); - unlock_kernel(); - return err; - } - ufs_put_super_internal(sb); usb1->fs_time = cpu_to_fs32(sb, get_seconds()); if ((flags & UFS_ST_MASK) == UFS_ST_SUN @@ -1342,14 +1326,11 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) return -EPERM; } sb->s_flags &= ~MS_RDONLY; - enable_quota = 1; #endif } UFS_SB(sb)->s_mount_opt = new_mount_opt; unlock_super(sb); unlock_kernel(); - if (enable_quota) - dquot_resume(sb, -1); return 0; } @@ -1453,126 +1434,19 @@ static void destroy_inodecache(void) kmem_cache_destroy(ufs_inode_cachep); } -static void ufs_clear_inode(struct inode *inode) -{ - dquot_drop(inode); -} - -#ifdef CONFIG_QUOTA -static ssize_t ufs_quota_read(struct super_block *, int, char *,size_t, loff_t); -static ssize_t ufs_quota_write(struct super_block *, int, const char *, size_t, loff_t); -#endif - static const struct super_operations ufs_super_ops = { .alloc_inode = ufs_alloc_inode, .destroy_inode = ufs_destroy_inode, .write_inode = ufs_write_inode, .delete_inode = ufs_delete_inode, - .clear_inode = ufs_clear_inode, .put_super = ufs_put_super, .write_super = ufs_write_super, .sync_fs = ufs_sync_fs, .statfs = ufs_statfs, .remount_fs = ufs_remount, .show_options = ufs_show_options, -#ifdef CONFIG_QUOTA - .quota_read = ufs_quota_read, - .quota_write = ufs_quota_write, -#endif }; -#ifdef CONFIG_QUOTA - -/* Read data from quotafile - avoid pagecache and such because we cannot afford - * acquiring the locks... As quota files are never truncated and quota code - * itself serializes the operations (and noone else should touch the files) - * we don't have to be afraid of races */ -static ssize_t ufs_quota_read(struct super_block *sb, int type, char *data, - size_t len, loff_t off) -{ - struct inode *inode = sb_dqopt(sb)->files[type]; - sector_t blk = off >> sb->s_blocksize_bits; - int err = 0; - int offset = off & (sb->s_blocksize - 1); - int tocopy; - size_t toread; - struct buffer_head *bh; - loff_t i_size = i_size_read(inode); - - if (off > i_size) - return 0; - if (off+len > i_size) - len = i_size-off; - toread = len; - while (toread > 0) { - tocopy = sb->s_blocksize - offset < toread ? - sb->s_blocksize - offset : toread; - - bh = ufs_bread(inode, blk, 0, &err); - if (err) - return err; - if (!bh) /* A hole? */ - memset(data, 0, tocopy); - else { - memcpy(data, bh->b_data+offset, tocopy); - brelse(bh); - } - offset = 0; - toread -= tocopy; - data += tocopy; - blk++; - } - return len; -} - -/* Write to quotafile */ -static ssize_t ufs_quota_write(struct super_block *sb, int type, - const char *data, size_t len, loff_t off) -{ - struct inode *inode = sb_dqopt(sb)->files[type]; - sector_t blk = off >> sb->s_blocksize_bits; - int err = 0; - int offset = off & (sb->s_blocksize - 1); - int tocopy; - size_t towrite = len; - struct buffer_head *bh; - - mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA); - while (towrite > 0) { - tocopy = sb->s_blocksize - offset < towrite ? - sb->s_blocksize - offset : towrite; - - bh = ufs_bread(inode, blk, 1, &err); - if (!bh) - goto out; - lock_buffer(bh); - memcpy(bh->b_data+offset, data, tocopy); - flush_dcache_page(bh->b_page); - set_buffer_uptodate(bh); - mark_buffer_dirty(bh); - unlock_buffer(bh); - brelse(bh); - offset = 0; - towrite -= tocopy; - data += tocopy; - blk++; - } -out: - if (len == towrite) { - mutex_unlock(&inode->i_mutex); - return err; - } - if (inode->i_size < off+len-towrite) - i_size_write(inode, off+len-towrite); - inode->i_version++; - inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC; - mark_inode_dirty(inode); - mutex_unlock(&inode->i_mutex); - return len - towrite; -} - -#endif - static int ufs_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *data, struct vfsmount *mnt) { -- cgit v1.2.3