Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs-2.6
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs-2.6: quota: Convert quota statistics to generic percpu_counter ext3 uses rb_node = NULL; to zero rb_root. quota: Fixup dquot_transfer reiserfs: Fix resuming of quotas on remount read-write pohmelfs: Remove dead quota code ufs: Remove dead quota code udf: Remove dead quota code quota: rename default quotactl methods to dquot_ quota: explicitly set ->dq_op and ->s_qcop quota: drop remount argument to ->quota_on and ->quota_off quota: move unmount handling into the filesystem quota: kill the vfs_dq_off and vfs_dq_quota_on_remount wrappers quota: move remount handling into the filesystem ocfs2: Fix use after free on remount read-only Fix up conflicts in fs/ext4/super.c and fs/ufs/file.c
This commit is contained in:
Коммит
d28619f156
|
@ -29,7 +29,6 @@
|
|||
#include <linux/slab.h>
|
||||
#include <linux/statfs.h>
|
||||
#include <linux/writeback.h>
|
||||
#include <linux/quotaops.h>
|
||||
|
||||
#include "netfs.h"
|
||||
|
||||
|
@ -969,13 +968,6 @@ int pohmelfs_setattr_raw(struct inode *inode, struct iattr *attr)
|
|||
goto err_out_exit;
|
||||
}
|
||||
|
||||
if ((attr->ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
|
||||
(attr->ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
|
||||
err = dquot_transfer(inode, attr);
|
||||
if (err)
|
||||
goto err_out_exit;
|
||||
}
|
||||
|
||||
err = inode_setattr(inode, attr);
|
||||
if (err) {
|
||||
dprintk("%s: ino: %llu, failed to set the attributes.\n", __func__, POHMELFS_I(inode)->ino);
|
||||
|
|
|
@ -119,6 +119,8 @@ static void ext2_put_super (struct super_block * sb)
|
|||
int i;
|
||||
struct ext2_sb_info *sbi = EXT2_SB(sb);
|
||||
|
||||
dquot_disable(sb, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED);
|
||||
|
||||
if (sb->s_dirt)
|
||||
ext2_write_super(sb);
|
||||
|
||||
|
@ -1063,6 +1065,12 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
|
|||
sb->s_op = &ext2_sops;
|
||||
sb->s_export_op = &ext2_export_ops;
|
||||
sb->s_xattr = ext2_xattr_handlers;
|
||||
|
||||
#ifdef CONFIG_QUOTA
|
||||
sb->dq_op = &dquot_operations;
|
||||
sb->s_qcop = &dquot_quotactl_ops;
|
||||
#endif
|
||||
|
||||
root = ext2_iget(sb, EXT2_ROOT_INO);
|
||||
if (IS_ERR(root)) {
|
||||
ret = PTR_ERR(root);
|
||||
|
@ -1241,6 +1249,7 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data)
|
|||
spin_unlock(&sbi->s_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* OK, we are remounting a valid rw partition rdonly, so set
|
||||
* the rdonly flag and then mark the partition as valid again.
|
||||
|
@ -1248,6 +1257,13 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data)
|
|||
es->s_state = cpu_to_le16(sbi->s_mount_state);
|
||||
es->s_mtime = cpu_to_le32(get_seconds());
|
||||
spin_unlock(&sbi->s_lock);
|
||||
|
||||
err = dquot_suspend(sb, -1);
|
||||
if (err < 0) {
|
||||
spin_lock(&sbi->s_lock);
|
||||
goto restore_opts;
|
||||
}
|
||||
|
||||
ext2_sync_super(sb, es, 1);
|
||||
} else {
|
||||
__le32 ret = EXT2_HAS_RO_COMPAT_FEATURE(sb,
|
||||
|
@ -1269,8 +1285,12 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data)
|
|||
if (!ext2_setup_super (sb, es, 0))
|
||||
sb->s_flags &= ~MS_RDONLY;
|
||||
spin_unlock(&sbi->s_lock);
|
||||
|
||||
ext2_write_super(sb);
|
||||
|
||||
dquot_resume(sb, -1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
restore_opts:
|
||||
sbi->s_mount_opt = old_opts.s_mount_opt;
|
||||
|
|
|
@ -297,7 +297,7 @@ static void free_rb_tree_fname(struct rb_root *root)
|
|||
kfree (old);
|
||||
}
|
||||
if (!parent)
|
||||
root->rb_node = NULL;
|
||||
*root = RB_ROOT;
|
||||
else if (parent->rb_left == n)
|
||||
parent->rb_left = NULL;
|
||||
else if (parent->rb_right == n)
|
||||
|
|
|
@ -410,6 +410,8 @@ static void ext3_put_super (struct super_block * sb)
|
|||
struct ext3_super_block *es = sbi->s_es;
|
||||
int i, err;
|
||||
|
||||
dquot_disable(sb, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED);
|
||||
|
||||
lock_kernel();
|
||||
|
||||
ext3_xattr_put_super(sb);
|
||||
|
@ -748,7 +750,7 @@ static int ext3_release_dquot(struct dquot *dquot);
|
|||
static int ext3_mark_dquot_dirty(struct dquot *dquot);
|
||||
static int ext3_write_info(struct super_block *sb, int type);
|
||||
static int ext3_quota_on(struct super_block *sb, int type, int format_id,
|
||||
char *path, int remount);
|
||||
char *path);
|
||||
static int ext3_quota_on_mount(struct super_block *sb, int type);
|
||||
static ssize_t ext3_quota_read(struct super_block *sb, int type, char *data,
|
||||
size_t len, loff_t off);
|
||||
|
@ -767,12 +769,12 @@ static const struct dquot_operations ext3_quota_operations = {
|
|||
|
||||
static const struct quotactl_ops ext3_qctl_operations = {
|
||||
.quota_on = ext3_quota_on,
|
||||
.quota_off = vfs_quota_off,
|
||||
.quota_sync = vfs_quota_sync,
|
||||
.get_info = vfs_get_dqinfo,
|
||||
.set_info = vfs_set_dqinfo,
|
||||
.get_dqblk = vfs_get_dqblk,
|
||||
.set_dqblk = vfs_set_dqblk
|
||||
.quota_off = dquot_quota_off,
|
||||
.quota_sync = dquot_quota_sync,
|
||||
.get_info = dquot_get_dqinfo,
|
||||
.set_info = dquot_set_dqinfo,
|
||||
.get_dqblk = dquot_get_dqblk,
|
||||
.set_dqblk = dquot_set_dqblk
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -1527,7 +1529,7 @@ static void ext3_orphan_cleanup (struct super_block * sb,
|
|||
/* Turn quotas off */
|
||||
for (i = 0; i < MAXQUOTAS; i++) {
|
||||
if (sb_dqopt(sb)->files[i])
|
||||
vfs_quota_off(sb, i, 0);
|
||||
dquot_quota_off(sb, i);
|
||||
}
|
||||
#endif
|
||||
sb->s_flags = s_flags; /* Restore MS_RDONLY status */
|
||||
|
@ -2551,6 +2553,7 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
|
|||
ext3_fsblk_t n_blocks_count = 0;
|
||||
unsigned long old_sb_flags;
|
||||
struct ext3_mount_options old_opts;
|
||||
int enable_quota = 0;
|
||||
int err;
|
||||
#ifdef CONFIG_QUOTA
|
||||
int i;
|
||||
|
@ -2597,6 +2600,10 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
|
|||
}
|
||||
|
||||
if (*flags & MS_RDONLY) {
|
||||
err = dquot_suspend(sb, -1);
|
||||
if (err < 0)
|
||||
goto restore_opts;
|
||||
|
||||
/*
|
||||
* First of all, the unconditional stuff we have to do
|
||||
* to disable replay of the journal when we next remount
|
||||
|
@ -2651,6 +2658,7 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
|
|||
goto restore_opts;
|
||||
if (!ext3_setup_super (sb, es, 0))
|
||||
sb->s_flags &= ~MS_RDONLY;
|
||||
enable_quota = 1;
|
||||
}
|
||||
}
|
||||
#ifdef CONFIG_QUOTA
|
||||
|
@ -2662,6 +2670,9 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
|
|||
#endif
|
||||
unlock_super(sb);
|
||||
unlock_kernel();
|
||||
|
||||
if (enable_quota)
|
||||
dquot_resume(sb, -1);
|
||||
return 0;
|
||||
restore_opts:
|
||||
sb->s_flags = old_sb_flags;
|
||||
|
@ -2851,24 +2862,21 @@ static int ext3_write_info(struct super_block *sb, int type)
|
|||
*/
|
||||
static int ext3_quota_on_mount(struct super_block *sb, int type)
|
||||
{
|
||||
return vfs_quota_on_mount(sb, EXT3_SB(sb)->s_qf_names[type],
|
||||
EXT3_SB(sb)->s_jquota_fmt, type);
|
||||
return dquot_quota_on_mount(sb, EXT3_SB(sb)->s_qf_names[type],
|
||||
EXT3_SB(sb)->s_jquota_fmt, type);
|
||||
}
|
||||
|
||||
/*
|
||||
* Standard function to be called on quota_on
|
||||
*/
|
||||
static int ext3_quota_on(struct super_block *sb, int type, int format_id,
|
||||
char *name, int remount)
|
||||
char *name)
|
||||
{
|
||||
int err;
|
||||
struct path path;
|
||||
|
||||
if (!test_opt(sb, QUOTA))
|
||||
return -EINVAL;
|
||||
/* When remounting, no checks are needed and in fact, name is NULL */
|
||||
if (remount)
|
||||
return vfs_quota_on(sb, type, format_id, name, remount);
|
||||
|
||||
err = kern_path(name, LOOKUP_FOLLOW, &path);
|
||||
if (err)
|
||||
|
@ -2906,7 +2914,7 @@ static int ext3_quota_on(struct super_block *sb, int type, int format_id,
|
|||
}
|
||||
}
|
||||
|
||||
err = vfs_quota_on_path(sb, type, format_id, &path);
|
||||
err = dquot_quota_on_path(sb, type, format_id, &path);
|
||||
path_put(&path);
|
||||
return err;
|
||||
}
|
||||
|
|
|
@ -646,6 +646,8 @@ static void ext4_put_super(struct super_block *sb)
|
|||
struct ext4_super_block *es = sbi->s_es;
|
||||
int i, err;
|
||||
|
||||
dquot_disable(sb, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED);
|
||||
|
||||
flush_workqueue(sbi->dio_unwritten_wq);
|
||||
destroy_workqueue(sbi->dio_unwritten_wq);
|
||||
|
||||
|
@ -1062,7 +1064,7 @@ static int ext4_release_dquot(struct dquot *dquot);
|
|||
static int ext4_mark_dquot_dirty(struct dquot *dquot);
|
||||
static int ext4_write_info(struct super_block *sb, int type);
|
||||
static int ext4_quota_on(struct super_block *sb, int type, int format_id,
|
||||
char *path, int remount);
|
||||
char *path);
|
||||
static int ext4_quota_on_mount(struct super_block *sb, int type);
|
||||
static ssize_t ext4_quota_read(struct super_block *sb, int type, char *data,
|
||||
size_t len, loff_t off);
|
||||
|
@ -1084,12 +1086,12 @@ static const struct dquot_operations ext4_quota_operations = {
|
|||
|
||||
static const struct quotactl_ops ext4_qctl_operations = {
|
||||
.quota_on = ext4_quota_on,
|
||||
.quota_off = vfs_quota_off,
|
||||
.quota_sync = vfs_quota_sync,
|
||||
.get_info = vfs_get_dqinfo,
|
||||
.set_info = vfs_set_dqinfo,
|
||||
.get_dqblk = vfs_get_dqblk,
|
||||
.set_dqblk = vfs_set_dqblk
|
||||
.quota_off = dquot_quota_off,
|
||||
.quota_sync = dquot_quota_sync,
|
||||
.get_info = dquot_get_dqinfo,
|
||||
.set_info = dquot_set_dqinfo,
|
||||
.get_dqblk = dquot_get_dqblk,
|
||||
.set_dqblk = dquot_set_dqblk
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -2054,7 +2056,7 @@ static void ext4_orphan_cleanup(struct super_block *sb,
|
|||
/* Turn quotas off */
|
||||
for (i = 0; i < MAXQUOTAS; i++) {
|
||||
if (sb_dqopt(sb)->files[i])
|
||||
vfs_quota_off(sb, i, 0);
|
||||
dquot_quota_off(sb, i);
|
||||
}
|
||||
#endif
|
||||
sb->s_flags = s_flags; /* Restore MS_RDONLY status */
|
||||
|
@ -3576,6 +3578,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
|
|||
ext4_fsblk_t n_blocks_count = 0;
|
||||
unsigned long old_sb_flags;
|
||||
struct ext4_mount_options old_opts;
|
||||
int enable_quota = 0;
|
||||
ext4_group_t g;
|
||||
unsigned int journal_ioprio = DEFAULT_JOURNAL_IOPRIO;
|
||||
int err;
|
||||
|
@ -3633,6 +3636,10 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
|
|||
}
|
||||
|
||||
if (*flags & MS_RDONLY) {
|
||||
err = dquot_suspend(sb, -1);
|
||||
if (err < 0)
|
||||
goto restore_opts;
|
||||
|
||||
/*
|
||||
* First of all, the unconditional stuff we have to do
|
||||
* to disable replay of the journal when we next remount
|
||||
|
@ -3701,6 +3708,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
|
|||
goto restore_opts;
|
||||
if (!ext4_setup_super(sb, es, 0))
|
||||
sb->s_flags &= ~MS_RDONLY;
|
||||
enable_quota = 1;
|
||||
}
|
||||
}
|
||||
ext4_setup_system_zone(sb);
|
||||
|
@ -3716,6 +3724,8 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
|
|||
#endif
|
||||
unlock_super(sb);
|
||||
unlock_kernel();
|
||||
if (enable_quota)
|
||||
dquot_resume(sb, -1);
|
||||
|
||||
ext4_msg(sb, KERN_INFO, "re-mounted. Opts: %s", orig_data);
|
||||
kfree(orig_data);
|
||||
|
@ -3913,24 +3923,21 @@ static int ext4_write_info(struct super_block *sb, int type)
|
|||
*/
|
||||
static int ext4_quota_on_mount(struct super_block *sb, int type)
|
||||
{
|
||||
return vfs_quota_on_mount(sb, EXT4_SB(sb)->s_qf_names[type],
|
||||
EXT4_SB(sb)->s_jquota_fmt, type);
|
||||
return dquot_quota_on_mount(sb, EXT4_SB(sb)->s_qf_names[type],
|
||||
EXT4_SB(sb)->s_jquota_fmt, type);
|
||||
}
|
||||
|
||||
/*
|
||||
* Standard function to be called on quota_on
|
||||
*/
|
||||
static int ext4_quota_on(struct super_block *sb, int type, int format_id,
|
||||
char *name, int remount)
|
||||
char *name)
|
||||
{
|
||||
int err;
|
||||
struct path path;
|
||||
|
||||
if (!test_opt(sb, QUOTA))
|
||||
return -EINVAL;
|
||||
/* When remounting, no checks are needed and in fact, name is NULL */
|
||||
if (remount)
|
||||
return vfs_quota_on(sb, type, format_id, name, remount);
|
||||
|
||||
err = kern_path(name, LOOKUP_FOLLOW, &path);
|
||||
if (err)
|
||||
|
@ -3969,7 +3976,7 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id,
|
|||
}
|
||||
}
|
||||
|
||||
err = vfs_quota_on_path(sb, type, format_id, &path);
|
||||
err = dquot_quota_on_path(sb, type, format_id, &path);
|
||||
path_put(&path);
|
||||
return err;
|
||||
}
|
||||
|
|
|
@ -179,6 +179,8 @@ static void jfs_put_super(struct super_block *sb)
|
|||
|
||||
jfs_info("In jfs_put_super");
|
||||
|
||||
dquot_disable(sb, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED);
|
||||
|
||||
lock_kernel();
|
||||
|
||||
rc = jfs_umount(sb);
|
||||
|
@ -396,10 +398,20 @@ static int jfs_remount(struct super_block *sb, int *flags, char *data)
|
|||
|
||||
JFS_SBI(sb)->flag = flag;
|
||||
ret = jfs_mount_rw(sb, 1);
|
||||
|
||||
/* mark the fs r/w for quota activity */
|
||||
sb->s_flags &= ~MS_RDONLY;
|
||||
|
||||
unlock_kernel();
|
||||
dquot_resume(sb, -1);
|
||||
return ret;
|
||||
}
|
||||
if ((!(sb->s_flags & MS_RDONLY)) && (*flags & MS_RDONLY)) {
|
||||
rc = dquot_suspend(sb, -1);
|
||||
if (rc < 0) {
|
||||
unlock_kernel();
|
||||
return rc;
|
||||
}
|
||||
rc = jfs_umount_rw(sb);
|
||||
JFS_SBI(sb)->flag = flag;
|
||||
unlock_kernel();
|
||||
|
@ -469,6 +481,10 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent)
|
|||
*/
|
||||
sb->s_op = &jfs_super_operations;
|
||||
sb->s_export_op = &jfs_export_operations;
|
||||
#ifdef CONFIG_QUOTA
|
||||
sb->dq_op = &dquot_operations;
|
||||
sb->s_qcop = &dquot_quotactl_ops;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Initialize direct-mapping inode/address-space
|
||||
|
|
|
@ -879,13 +879,15 @@ static int ocfs2_susp_quotas(struct ocfs2_super *osb, int unsuspend)
|
|||
if (!OCFS2_HAS_RO_COMPAT_FEATURE(sb, feature[type]))
|
||||
continue;
|
||||
if (unsuspend)
|
||||
status = vfs_quota_enable(
|
||||
sb_dqopt(sb)->files[type],
|
||||
type, QFMT_OCFS2,
|
||||
DQUOT_SUSPENDED);
|
||||
else
|
||||
status = vfs_quota_disable(sb, type,
|
||||
DQUOT_SUSPENDED);
|
||||
status = dquot_resume(sb, type);
|
||||
else {
|
||||
struct ocfs2_mem_dqinfo *oinfo;
|
||||
|
||||
/* Cancel periodic syncing before suspending */
|
||||
oinfo = sb_dqinfo(sb, type)->dqi_priv;
|
||||
cancel_delayed_work_sync(&oinfo->dqi_sync_work);
|
||||
status = dquot_suspend(sb, type);
|
||||
}
|
||||
if (status < 0)
|
||||
break;
|
||||
}
|
||||
|
@ -916,8 +918,8 @@ static int ocfs2_enable_quotas(struct ocfs2_super *osb)
|
|||
status = -ENOENT;
|
||||
goto out_quota_off;
|
||||
}
|
||||
status = vfs_quota_enable(inode[type], type, QFMT_OCFS2,
|
||||
DQUOT_USAGE_ENABLED);
|
||||
status = dquot_enable(inode[type], type, QFMT_OCFS2,
|
||||
DQUOT_USAGE_ENABLED);
|
||||
if (status < 0)
|
||||
goto out_quota_off;
|
||||
}
|
||||
|
@ -952,8 +954,8 @@ static void ocfs2_disable_quotas(struct ocfs2_super *osb)
|
|||
/* Turn off quotas. This will remove all dquot structures from
|
||||
* memory and so they will be automatically synced to global
|
||||
* quota files */
|
||||
vfs_quota_disable(sb, type, DQUOT_USAGE_ENABLED |
|
||||
DQUOT_LIMITS_ENABLED);
|
||||
dquot_disable(sb, type, DQUOT_USAGE_ENABLED |
|
||||
DQUOT_LIMITS_ENABLED);
|
||||
if (!inode)
|
||||
continue;
|
||||
iput(inode);
|
||||
|
@ -962,7 +964,7 @@ static void ocfs2_disable_quotas(struct ocfs2_super *osb)
|
|||
|
||||
/* Handle quota on quotactl */
|
||||
static int ocfs2_quota_on(struct super_block *sb, int type, int format_id,
|
||||
char *path, int remount)
|
||||
char *path)
|
||||
{
|
||||
unsigned int feature[MAXQUOTAS] = { OCFS2_FEATURE_RO_COMPAT_USRQUOTA,
|
||||
OCFS2_FEATURE_RO_COMPAT_GRPQUOTA};
|
||||
|
@ -970,30 +972,24 @@ static int ocfs2_quota_on(struct super_block *sb, int type, int format_id,
|
|||
if (!OCFS2_HAS_RO_COMPAT_FEATURE(sb, feature[type]))
|
||||
return -EINVAL;
|
||||
|
||||
if (remount)
|
||||
return 0; /* Just ignore it has been handled in
|
||||
* ocfs2_remount() */
|
||||
return vfs_quota_enable(sb_dqopt(sb)->files[type], type,
|
||||
format_id, DQUOT_LIMITS_ENABLED);
|
||||
return dquot_enable(sb_dqopt(sb)->files[type], type,
|
||||
format_id, DQUOT_LIMITS_ENABLED);
|
||||
}
|
||||
|
||||
/* Handle quota off quotactl */
|
||||
static int ocfs2_quota_off(struct super_block *sb, int type, int remount)
|
||||
static int ocfs2_quota_off(struct super_block *sb, int type)
|
||||
{
|
||||
if (remount)
|
||||
return 0; /* Ignore now and handle later in
|
||||
* ocfs2_remount() */
|
||||
return vfs_quota_disable(sb, type, DQUOT_LIMITS_ENABLED);
|
||||
return dquot_disable(sb, type, DQUOT_LIMITS_ENABLED);
|
||||
}
|
||||
|
||||
static const struct quotactl_ops ocfs2_quotactl_ops = {
|
||||
.quota_on = ocfs2_quota_on,
|
||||
.quota_off = ocfs2_quota_off,
|
||||
.quota_sync = vfs_quota_sync,
|
||||
.get_info = vfs_get_dqinfo,
|
||||
.set_info = vfs_set_dqinfo,
|
||||
.get_dqblk = vfs_get_dqblk,
|
||||
.set_dqblk = vfs_set_dqblk,
|
||||
.quota_sync = dquot_quota_sync,
|
||||
.get_info = dquot_get_dqinfo,
|
||||
.set_info = dquot_set_dqinfo,
|
||||
.get_dqblk = dquot_get_dqblk,
|
||||
.set_dqblk = dquot_set_dqblk,
|
||||
};
|
||||
|
||||
static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
|
||||
|
|
192
fs/quota/dquot.c
192
fs/quota/dquot.c
|
@ -228,10 +228,6 @@ static struct hlist_head *dquot_hash;
|
|||
|
||||
struct dqstats dqstats;
|
||||
EXPORT_SYMBOL(dqstats);
|
||||
#ifdef CONFIG_SMP
|
||||
struct dqstats *dqstats_pcpu;
|
||||
EXPORT_SYMBOL(dqstats_pcpu);
|
||||
#endif
|
||||
|
||||
static qsize_t inode_get_rsv_space(struct inode *inode);
|
||||
static void __dquot_initialize(struct inode *inode, int type);
|
||||
|
@ -584,7 +580,7 @@ out:
|
|||
}
|
||||
EXPORT_SYMBOL(dquot_scan_active);
|
||||
|
||||
int vfs_quota_sync(struct super_block *sb, int type, int wait)
|
||||
int dquot_quota_sync(struct super_block *sb, int type, int wait)
|
||||
{
|
||||
struct list_head *dirty;
|
||||
struct dquot *dquot;
|
||||
|
@ -656,7 +652,7 @@ int vfs_quota_sync(struct super_block *sb, int type, int wait)
|
|||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(vfs_quota_sync);
|
||||
EXPORT_SYMBOL(dquot_quota_sync);
|
||||
|
||||
/* Free unused dquots from cache */
|
||||
static void prune_dqcache(int count)
|
||||
|
@ -676,27 +672,10 @@ static void prune_dqcache(int count)
|
|||
}
|
||||
}
|
||||
|
||||
static int dqstats_read(unsigned int type)
|
||||
{
|
||||
int count = 0;
|
||||
#ifdef CONFIG_SMP
|
||||
int cpu;
|
||||
for_each_possible_cpu(cpu)
|
||||
count += per_cpu_ptr(dqstats_pcpu, cpu)->stat[type];
|
||||
/* Statistics reading is racy, but absolute accuracy isn't required */
|
||||
if (count < 0)
|
||||
count = 0;
|
||||
#else
|
||||
count = dqstats.stat[type];
|
||||
#endif
|
||||
return count;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is called from kswapd when we think we need some
|
||||
* more memory
|
||||
*/
|
||||
|
||||
static int shrink_dqcache_memory(int nr, gfp_t gfp_mask)
|
||||
{
|
||||
if (nr) {
|
||||
|
@ -704,7 +683,9 @@ static int shrink_dqcache_memory(int nr, gfp_t gfp_mask)
|
|||
prune_dqcache(nr);
|
||||
spin_unlock(&dq_list_lock);
|
||||
}
|
||||
return (dqstats_read(DQST_FREE_DQUOTS)/100) * sysctl_vfs_cache_pressure;
|
||||
return ((unsigned)
|
||||
percpu_counter_read_positive(&dqstats.counter[DQST_FREE_DQUOTS])
|
||||
/100) * sysctl_vfs_cache_pressure;
|
||||
}
|
||||
|
||||
static struct shrinker dqcache_shrinker = {
|
||||
|
@ -1815,7 +1796,7 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr)
|
|||
if (iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid)
|
||||
transfer_to[USRQUOTA] = dqget(sb, iattr->ia_uid, USRQUOTA);
|
||||
if (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)
|
||||
transfer_to[GRPQUOTA] = dqget(sb, iattr->ia_uid, GRPQUOTA);
|
||||
transfer_to[GRPQUOTA] = dqget(sb, iattr->ia_gid, GRPQUOTA);
|
||||
|
||||
ret = __dquot_transfer(inode, transfer_to);
|
||||
dqput_all(transfer_to);
|
||||
|
@ -1850,6 +1831,7 @@ const struct dquot_operations dquot_operations = {
|
|||
.alloc_dquot = dquot_alloc,
|
||||
.destroy_dquot = dquot_destroy,
|
||||
};
|
||||
EXPORT_SYMBOL(dquot_operations);
|
||||
|
||||
/*
|
||||
* Generic helper for ->open on filesystems supporting disk quotas.
|
||||
|
@ -1868,7 +1850,7 @@ EXPORT_SYMBOL(dquot_file_open);
|
|||
/*
|
||||
* Turn quota off on a device. type == -1 ==> quotaoff for all types (umount)
|
||||
*/
|
||||
int vfs_quota_disable(struct super_block *sb, int type, unsigned int flags)
|
||||
int dquot_disable(struct super_block *sb, int type, unsigned int flags)
|
||||
{
|
||||
int cnt, ret = 0;
|
||||
struct quota_info *dqopt = sb_dqopt(sb);
|
||||
|
@ -1998,14 +1980,15 @@ put_inodes:
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(vfs_quota_disable);
|
||||
EXPORT_SYMBOL(dquot_disable);
|
||||
|
||||
int vfs_quota_off(struct super_block *sb, int type, int remount)
|
||||
int dquot_quota_off(struct super_block *sb, int type)
|
||||
{
|
||||
return vfs_quota_disable(sb, type, remount ? DQUOT_SUSPENDED :
|
||||
(DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED));
|
||||
return dquot_disable(sb, type,
|
||||
DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED);
|
||||
}
|
||||
EXPORT_SYMBOL(vfs_quota_off);
|
||||
EXPORT_SYMBOL(dquot_quota_off);
|
||||
|
||||
/*
|
||||
* Turn quotas on on a device
|
||||
*/
|
||||
|
@ -2123,36 +2106,43 @@ out_fmt:
|
|||
}
|
||||
|
||||
/* Reenable quotas on remount RW */
|
||||
static int vfs_quota_on_remount(struct super_block *sb, int type)
|
||||
int dquot_resume(struct super_block *sb, int type)
|
||||
{
|
||||
struct quota_info *dqopt = sb_dqopt(sb);
|
||||
struct inode *inode;
|
||||
int ret;
|
||||
int ret = 0, cnt;
|
||||
unsigned int flags;
|
||||
|
||||
mutex_lock(&dqopt->dqonoff_mutex);
|
||||
if (!sb_has_quota_suspended(sb, type)) {
|
||||
mutex_unlock(&dqopt->dqonoff_mutex);
|
||||
return 0;
|
||||
}
|
||||
inode = dqopt->files[type];
|
||||
dqopt->files[type] = NULL;
|
||||
spin_lock(&dq_state_lock);
|
||||
flags = dqopt->flags & dquot_state_flag(DQUOT_USAGE_ENABLED |
|
||||
DQUOT_LIMITS_ENABLED, type);
|
||||
dqopt->flags &= ~dquot_state_flag(DQUOT_STATE_FLAGS, type);
|
||||
spin_unlock(&dq_state_lock);
|
||||
mutex_unlock(&dqopt->dqonoff_mutex);
|
||||
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
|
||||
if (type != -1 && cnt != type)
|
||||
continue;
|
||||
|
||||
flags = dquot_generic_flag(flags, type);
|
||||
ret = vfs_load_quota_inode(inode, type, dqopt->info[type].dqi_fmt_id,
|
||||
flags);
|
||||
iput(inode);
|
||||
mutex_lock(&dqopt->dqonoff_mutex);
|
||||
if (!sb_has_quota_suspended(sb, cnt)) {
|
||||
mutex_unlock(&dqopt->dqonoff_mutex);
|
||||
continue;
|
||||
}
|
||||
inode = dqopt->files[cnt];
|
||||
dqopt->files[cnt] = NULL;
|
||||
spin_lock(&dq_state_lock);
|
||||
flags = dqopt->flags & dquot_state_flag(DQUOT_USAGE_ENABLED |
|
||||
DQUOT_LIMITS_ENABLED,
|
||||
cnt);
|
||||
dqopt->flags &= ~dquot_state_flag(DQUOT_STATE_FLAGS, cnt);
|
||||
spin_unlock(&dq_state_lock);
|
||||
mutex_unlock(&dqopt->dqonoff_mutex);
|
||||
|
||||
flags = dquot_generic_flag(flags, cnt);
|
||||
ret = vfs_load_quota_inode(inode, cnt,
|
||||
dqopt->info[cnt].dqi_fmt_id, flags);
|
||||
iput(inode);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(dquot_resume);
|
||||
|
||||
int vfs_quota_on_path(struct super_block *sb, int type, int format_id,
|
||||
int dquot_quota_on_path(struct super_block *sb, int type, int format_id,
|
||||
struct path *path)
|
||||
{
|
||||
int error = security_quota_on(path->dentry);
|
||||
|
@ -2167,40 +2157,36 @@ int vfs_quota_on_path(struct super_block *sb, int type, int format_id,
|
|||
DQUOT_LIMITS_ENABLED);
|
||||
return error;
|
||||
}
|
||||
EXPORT_SYMBOL(vfs_quota_on_path);
|
||||
EXPORT_SYMBOL(dquot_quota_on_path);
|
||||
|
||||
int vfs_quota_on(struct super_block *sb, int type, int format_id, char *name,
|
||||
int remount)
|
||||
int dquot_quota_on(struct super_block *sb, int type, int format_id, char *name)
|
||||
{
|
||||
struct path path;
|
||||
int error;
|
||||
|
||||
if (remount)
|
||||
return vfs_quota_on_remount(sb, type);
|
||||
|
||||
error = kern_path(name, LOOKUP_FOLLOW, &path);
|
||||
if (!error) {
|
||||
error = vfs_quota_on_path(sb, type, format_id, &path);
|
||||
error = dquot_quota_on_path(sb, type, format_id, &path);
|
||||
path_put(&path);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
EXPORT_SYMBOL(vfs_quota_on);
|
||||
EXPORT_SYMBOL(dquot_quota_on);
|
||||
|
||||
/*
|
||||
* More powerful function for turning on quotas allowing setting
|
||||
* of individual quota flags
|
||||
*/
|
||||
int vfs_quota_enable(struct inode *inode, int type, int format_id,
|
||||
unsigned int flags)
|
||||
int dquot_enable(struct inode *inode, int type, int format_id,
|
||||
unsigned int flags)
|
||||
{
|
||||
int ret = 0;
|
||||
struct super_block *sb = inode->i_sb;
|
||||
struct quota_info *dqopt = sb_dqopt(sb);
|
||||
|
||||
/* Just unsuspend quotas? */
|
||||
if (flags & DQUOT_SUSPENDED)
|
||||
return vfs_quota_on_remount(sb, type);
|
||||
BUG_ON(flags & DQUOT_SUSPENDED);
|
||||
|
||||
if (!flags)
|
||||
return 0;
|
||||
/* Just updating flags needed? */
|
||||
|
@ -2232,13 +2218,13 @@ out_lock:
|
|||
load_quota:
|
||||
return vfs_load_quota_inode(inode, type, format_id, flags);
|
||||
}
|
||||
EXPORT_SYMBOL(vfs_quota_enable);
|
||||
EXPORT_SYMBOL(dquot_enable);
|
||||
|
||||
/*
|
||||
* This function is used when filesystem needs to initialize quotas
|
||||
* during mount time.
|
||||
*/
|
||||
int vfs_quota_on_mount(struct super_block *sb, char *qf_name,
|
||||
int dquot_quota_on_mount(struct super_block *sb, char *qf_name,
|
||||
int format_id, int type)
|
||||
{
|
||||
struct dentry *dentry;
|
||||
|
@ -2264,24 +2250,7 @@ out:
|
|||
dput(dentry);
|
||||
return error;
|
||||
}
|
||||
EXPORT_SYMBOL(vfs_quota_on_mount);
|
||||
|
||||
/* Wrapper to turn on quotas when remounting rw */
|
||||
int vfs_dq_quota_on_remount(struct super_block *sb)
|
||||
{
|
||||
int cnt;
|
||||
int ret = 0, err;
|
||||
|
||||
if (!sb->s_qcop || !sb->s_qcop->quota_on)
|
||||
return -ENOSYS;
|
||||
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
|
||||
err = sb->s_qcop->quota_on(sb, cnt, 0, NULL, 1);
|
||||
if (err < 0 && !ret)
|
||||
ret = err;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(vfs_dq_quota_on_remount);
|
||||
EXPORT_SYMBOL(dquot_quota_on_mount);
|
||||
|
||||
static inline qsize_t qbtos(qsize_t blocks)
|
||||
{
|
||||
|
@ -2316,8 +2285,8 @@ static void do_get_dqblk(struct dquot *dquot, struct fs_disk_quota *di)
|
|||
spin_unlock(&dq_data_lock);
|
||||
}
|
||||
|
||||
int vfs_get_dqblk(struct super_block *sb, int type, qid_t id,
|
||||
struct fs_disk_quota *di)
|
||||
int dquot_get_dqblk(struct super_block *sb, int type, qid_t id,
|
||||
struct fs_disk_quota *di)
|
||||
{
|
||||
struct dquot *dquot;
|
||||
|
||||
|
@ -2329,7 +2298,7 @@ int vfs_get_dqblk(struct super_block *sb, int type, qid_t id,
|
|||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(vfs_get_dqblk);
|
||||
EXPORT_SYMBOL(dquot_get_dqblk);
|
||||
|
||||
#define VFS_FS_DQ_MASK \
|
||||
(FS_DQ_BCOUNT | FS_DQ_BSOFT | FS_DQ_BHARD | \
|
||||
|
@ -2428,7 +2397,7 @@ static int do_set_dqblk(struct dquot *dquot, struct fs_disk_quota *di)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int vfs_set_dqblk(struct super_block *sb, int type, qid_t id,
|
||||
int dquot_set_dqblk(struct super_block *sb, int type, qid_t id,
|
||||
struct fs_disk_quota *di)
|
||||
{
|
||||
struct dquot *dquot;
|
||||
|
@ -2444,10 +2413,10 @@ int vfs_set_dqblk(struct super_block *sb, int type, qid_t id,
|
|||
out:
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL(vfs_set_dqblk);
|
||||
EXPORT_SYMBOL(dquot_set_dqblk);
|
||||
|
||||
/* Generic routine for getting common part of quota file information */
|
||||
int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
|
||||
int dquot_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
|
||||
{
|
||||
struct mem_dqinfo *mi;
|
||||
|
||||
|
@ -2466,10 +2435,10 @@ int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
|
|||
mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(vfs_get_dqinfo);
|
||||
EXPORT_SYMBOL(dquot_get_dqinfo);
|
||||
|
||||
/* Generic routine for setting common part of quota file information */
|
||||
int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
|
||||
int dquot_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
|
||||
{
|
||||
struct mem_dqinfo *mi;
|
||||
int err = 0;
|
||||
|
@ -2496,27 +2465,27 @@ out:
|
|||
mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(vfs_set_dqinfo);
|
||||
EXPORT_SYMBOL(dquot_set_dqinfo);
|
||||
|
||||
const struct quotactl_ops vfs_quotactl_ops = {
|
||||
.quota_on = vfs_quota_on,
|
||||
.quota_off = vfs_quota_off,
|
||||
.quota_sync = vfs_quota_sync,
|
||||
.get_info = vfs_get_dqinfo,
|
||||
.set_info = vfs_set_dqinfo,
|
||||
.get_dqblk = vfs_get_dqblk,
|
||||
.set_dqblk = vfs_set_dqblk
|
||||
const struct quotactl_ops dquot_quotactl_ops = {
|
||||
.quota_on = dquot_quota_on,
|
||||
.quota_off = dquot_quota_off,
|
||||
.quota_sync = dquot_quota_sync,
|
||||
.get_info = dquot_get_dqinfo,
|
||||
.set_info = dquot_set_dqinfo,
|
||||
.get_dqblk = dquot_get_dqblk,
|
||||
.set_dqblk = dquot_set_dqblk
|
||||
};
|
||||
|
||||
EXPORT_SYMBOL(dquot_quotactl_ops);
|
||||
|
||||
static int do_proc_dqstats(struct ctl_table *table, int write,
|
||||
void __user *buffer, size_t *lenp, loff_t *ppos)
|
||||
{
|
||||
#ifdef CONFIG_SMP
|
||||
/* Update global table */
|
||||
unsigned int type = (int *)table->data - dqstats.stat;
|
||||
dqstats.stat[type] = dqstats_read(type);
|
||||
#endif
|
||||
|
||||
/* Update global table */
|
||||
dqstats.stat[type] =
|
||||
percpu_counter_sum_positive(&dqstats.counter[type]);
|
||||
return proc_dointvec(table, write, buffer, lenp, ppos);
|
||||
}
|
||||
|
||||
|
@ -2609,7 +2578,7 @@ static ctl_table sys_table[] = {
|
|||
|
||||
static int __init dquot_init(void)
|
||||
{
|
||||
int i;
|
||||
int i, ret;
|
||||
unsigned long nr_hash, order;
|
||||
|
||||
printk(KERN_NOTICE "VFS: Disk quotas %s\n", __DQUOT_VERSION__);
|
||||
|
@ -2627,12 +2596,11 @@ static int __init dquot_init(void)
|
|||
if (!dquot_hash)
|
||||
panic("Cannot create dquot hash table");
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
dqstats_pcpu = alloc_percpu(struct dqstats);
|
||||
if (!dqstats_pcpu)
|
||||
panic("Cannot create dquot stats table");
|
||||
#endif
|
||||
memset(&dqstats, 0, sizeof(struct dqstats));
|
||||
for (i = 0; i < _DQST_DQSTAT_LAST; i++) {
|
||||
ret = percpu_counter_init(&dqstats.counter[i], 0);
|
||||
if (ret)
|
||||
panic("Cannot create dquot stat counters");
|
||||
}
|
||||
|
||||
/* Find power-of-two hlist_heads which can fit into allocation */
|
||||
nr_hash = (1UL << order) * PAGE_SIZE / sizeof(struct hlist_head);
|
||||
|
|
|
@ -73,7 +73,7 @@ static int quota_quotaon(struct super_block *sb, int type, int cmd, qid_t id,
|
|||
if (IS_ERR(pathname))
|
||||
return PTR_ERR(pathname);
|
||||
if (sb->s_qcop->quota_on)
|
||||
ret = sb->s_qcop->quota_on(sb, type, id, pathname, 0);
|
||||
ret = sb->s_qcop->quota_on(sb, type, id, pathname);
|
||||
putname(pathname);
|
||||
return ret;
|
||||
}
|
||||
|
@ -260,7 +260,7 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id,
|
|||
case Q_QUOTAOFF:
|
||||
if (!sb->s_qcop->quota_off)
|
||||
return -ENOSYS;
|
||||
return sb->s_qcop->quota_off(sb, type, 0);
|
||||
return sb->s_qcop->quota_off(sb, type);
|
||||
case Q_GETFMT:
|
||||
return quota_getfmt(sb, type, addr);
|
||||
case Q_GETINFO:
|
||||
|
|
|
@ -158,6 +158,7 @@ static int finish_unfinished(struct super_block *s)
|
|||
#ifdef CONFIG_QUOTA
|
||||
int i;
|
||||
int ms_active_set;
|
||||
int quota_enabled[MAXQUOTAS];
|
||||
#endif
|
||||
|
||||
/* compose key to look for "save" links */
|
||||
|
@ -179,8 +180,15 @@ static int finish_unfinished(struct super_block *s)
|
|||
}
|
||||
/* Turn on quotas so that they are updated correctly */
|
||||
for (i = 0; i < MAXQUOTAS; i++) {
|
||||
quota_enabled[i] = 1;
|
||||
if (REISERFS_SB(s)->s_qf_names[i]) {
|
||||
int ret = reiserfs_quota_on_mount(s, i);
|
||||
int ret;
|
||||
|
||||
if (sb_has_quota_active(s, i)) {
|
||||
quota_enabled[i] = 0;
|
||||
continue;
|
||||
}
|
||||
ret = reiserfs_quota_on_mount(s, i);
|
||||
if (ret < 0)
|
||||
reiserfs_warning(s, "reiserfs-2500",
|
||||
"cannot turn on journaled "
|
||||
|
@ -304,8 +312,8 @@ static int finish_unfinished(struct super_block *s)
|
|||
#ifdef CONFIG_QUOTA
|
||||
/* Turn quotas off */
|
||||
for (i = 0; i < MAXQUOTAS; i++) {
|
||||
if (sb_dqopt(s)->files[i])
|
||||
vfs_quota_off(s, i, 0);
|
||||
if (sb_dqopt(s)->files[i] && quota_enabled[i])
|
||||
dquot_quota_off(s, i);
|
||||
}
|
||||
if (ms_active_set)
|
||||
/* Restore the flag back */
|
||||
|
@ -466,6 +474,8 @@ static void reiserfs_put_super(struct super_block *s)
|
|||
struct reiserfs_transaction_handle th;
|
||||
th.t_trans_id = 0;
|
||||
|
||||
dquot_disable(s, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED);
|
||||
|
||||
reiserfs_write_lock(s);
|
||||
|
||||
if (s->s_dirt)
|
||||
|
@ -620,7 +630,7 @@ static int reiserfs_acquire_dquot(struct dquot *);
|
|||
static int reiserfs_release_dquot(struct dquot *);
|
||||
static int reiserfs_mark_dquot_dirty(struct dquot *);
|
||||
static int reiserfs_write_info(struct super_block *, int);
|
||||
static int reiserfs_quota_on(struct super_block *, int, int, char *, int);
|
||||
static int reiserfs_quota_on(struct super_block *, int, int, char *);
|
||||
|
||||
static const struct dquot_operations reiserfs_quota_operations = {
|
||||
.write_dquot = reiserfs_write_dquot,
|
||||
|
@ -634,12 +644,12 @@ static const struct dquot_operations reiserfs_quota_operations = {
|
|||
|
||||
static const struct quotactl_ops reiserfs_qctl_operations = {
|
||||
.quota_on = reiserfs_quota_on,
|
||||
.quota_off = vfs_quota_off,
|
||||
.quota_sync = vfs_quota_sync,
|
||||
.get_info = vfs_get_dqinfo,
|
||||
.set_info = vfs_set_dqinfo,
|
||||
.get_dqblk = vfs_get_dqblk,
|
||||
.set_dqblk = vfs_set_dqblk,
|
||||
.quota_off = dquot_quota_off,
|
||||
.quota_sync = dquot_quota_sync,
|
||||
.get_info = dquot_get_dqinfo,
|
||||
.set_info = dquot_set_dqinfo,
|
||||
.get_dqblk = dquot_get_dqblk,
|
||||
.set_dqblk = dquot_set_dqblk,
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -1242,6 +1252,11 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
|
|||
if (s->s_flags & MS_RDONLY)
|
||||
/* it is read-only already */
|
||||
goto out_ok;
|
||||
|
||||
err = dquot_suspend(s, -1);
|
||||
if (err < 0)
|
||||
goto out_err;
|
||||
|
||||
/* try to remount file system with read-only permissions */
|
||||
if (sb_umount_state(rs) == REISERFS_VALID_FS
|
||||
|| REISERFS_SB(s)->s_mount_state != REISERFS_VALID_FS) {
|
||||
|
@ -1295,6 +1310,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
|
|||
s->s_dirt = 0;
|
||||
|
||||
if (!(*mount_flags & MS_RDONLY)) {
|
||||
dquot_resume(s, -1);
|
||||
finish_unfinished(s);
|
||||
reiserfs_xattr_init(s, *mount_flags);
|
||||
}
|
||||
|
@ -2022,15 +2038,15 @@ static int reiserfs_write_info(struct super_block *sb, int type)
|
|||
*/
|
||||
static int reiserfs_quota_on_mount(struct super_block *sb, int type)
|
||||
{
|
||||
return vfs_quota_on_mount(sb, REISERFS_SB(sb)->s_qf_names[type],
|
||||
REISERFS_SB(sb)->s_jquota_fmt, type);
|
||||
return dquot_quota_on_mount(sb, REISERFS_SB(sb)->s_qf_names[type],
|
||||
REISERFS_SB(sb)->s_jquota_fmt, type);
|
||||
}
|
||||
|
||||
/*
|
||||
* Standard function to be called on quota_on
|
||||
*/
|
||||
static int reiserfs_quota_on(struct super_block *sb, int type, int format_id,
|
||||
char *name, int remount)
|
||||
char *name)
|
||||
{
|
||||
int err;
|
||||
struct path path;
|
||||
|
@ -2039,9 +2055,7 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id,
|
|||
|
||||
if (!(REISERFS_SB(sb)->s_mount_opt & (1 << REISERFS_QUOTA)))
|
||||
return -EINVAL;
|
||||
/* No more checks needed? Path and format_id are bogus anyway... */
|
||||
if (remount)
|
||||
return vfs_quota_on(sb, type, format_id, name, 1);
|
||||
|
||||
err = kern_path(name, LOOKUP_FOLLOW, &path);
|
||||
if (err)
|
||||
return err;
|
||||
|
@ -2085,7 +2099,7 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id,
|
|||
if (err)
|
||||
goto out;
|
||||
}
|
||||
err = vfs_quota_on_path(sb, type, format_id, &path);
|
||||
err = dquot_quota_on_path(sb, type, format_id, &path);
|
||||
out:
|
||||
path_put(&path);
|
||||
return err;
|
||||
|
|
13
fs/super.c
13
fs/super.c
|
@ -24,7 +24,6 @@
|
|||
#include <linux/slab.h>
|
||||
#include <linux/acct.h>
|
||||
#include <linux/blkdev.h>
|
||||
#include <linux/quotaops.h>
|
||||
#include <linux/mount.h>
|
||||
#include <linux/security.h>
|
||||
#include <linux/writeback.h> /* for the emergency remount stuff */
|
||||
|
@ -94,8 +93,6 @@ static struct super_block *alloc_super(struct file_system_type *type)
|
|||
init_rwsem(&s->s_dquot.dqptr_sem);
|
||||
init_waitqueue_head(&s->s_wait_unfrozen);
|
||||
s->s_maxbytes = MAX_NON_LFS;
|
||||
s->dq_op = sb_dquot_ops;
|
||||
s->s_qcop = sb_quotactl_ops;
|
||||
s->s_op = &default_op;
|
||||
s->s_time_gran = 1000000000;
|
||||
}
|
||||
|
@ -160,7 +157,6 @@ void deactivate_locked_super(struct super_block *s)
|
|||
{
|
||||
struct file_system_type *fs = s->s_type;
|
||||
if (atomic_dec_and_test(&s->s_active)) {
|
||||
vfs_dq_off(s, 0);
|
||||
fs->kill_sb(s);
|
||||
put_filesystem(fs);
|
||||
put_super(s);
|
||||
|
@ -524,7 +520,7 @@ rescan:
|
|||
int do_remount_sb(struct super_block *sb, int flags, void *data, int force)
|
||||
{
|
||||
int retval;
|
||||
int remount_rw, remount_ro;
|
||||
int remount_ro;
|
||||
|
||||
if (sb->s_frozen != SB_UNFROZEN)
|
||||
return -EBUSY;
|
||||
|
@ -540,7 +536,6 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force)
|
|||
sync_filesystem(sb);
|
||||
|
||||
remount_ro = (flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY);
|
||||
remount_rw = !(flags & MS_RDONLY) && (sb->s_flags & MS_RDONLY);
|
||||
|
||||
/* If we are remounting RDONLY and current sb is read/write,
|
||||
make sure there are no rw files opened */
|
||||
|
@ -549,9 +544,6 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force)
|
|||
mark_files_ro(sb);
|
||||
else if (!fs_may_remount_ro(sb))
|
||||
return -EBUSY;
|
||||
retval = vfs_dq_off(sb, 1);
|
||||
if (retval < 0 && retval != -ENOSYS)
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
if (sb->s_op->remount_fs) {
|
||||
|
@ -560,8 +552,7 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force)
|
|||
return retval;
|
||||
}
|
||||
sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) | (flags & MS_RMT_MASK);
|
||||
if (remount_rw)
|
||||
vfs_dq_quota_on_remount(sb);
|
||||
|
||||
/*
|
||||
* Some filesystems modify their metadata via some other path than the
|
||||
* bdev buffer cache (eg. use a private mapping, or directories in
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
|
||||
#include "udfdecl.h"
|
||||
|
||||
#include <linux/quotaops.h>
|
||||
#include <linux/buffer_head.h>
|
||||
#include <linux/bitops.h>
|
||||
|
||||
|
@ -159,8 +158,6 @@ static void udf_bitmap_free_blocks(struct super_block *sb,
|
|||
udf_debug("byte=%2x\n",
|
||||
((char *)bh->b_data)[(bit + i) >> 3]);
|
||||
} else {
|
||||
if (inode)
|
||||
dquot_free_block(inode, 1);
|
||||
udf_add_free_space(sb, sbi->s_partition, 1);
|
||||
}
|
||||
}
|
||||
|
@ -210,15 +207,8 @@ static int udf_bitmap_prealloc_blocks(struct super_block *sb,
|
|||
bit = block % (sb->s_blocksize << 3);
|
||||
|
||||
while (bit < (sb->s_blocksize << 3) && block_count > 0) {
|
||||
if (!udf_test_bit(bit, bh->b_data))
|
||||
if (!udf_clear_bit(bit, bh->b_data))
|
||||
goto out;
|
||||
else if (dquot_prealloc_block(inode, 1))
|
||||
goto out;
|
||||
else if (!udf_clear_bit(bit, bh->b_data)) {
|
||||
udf_debug("bit already cleared for block %d\n", bit);
|
||||
dquot_free_block(inode, 1);
|
||||
goto out;
|
||||
}
|
||||
block_count--;
|
||||
alloc_count++;
|
||||
bit++;
|
||||
|
@ -338,20 +328,6 @@ search_back:
|
|||
}
|
||||
|
||||
got_block:
|
||||
|
||||
/*
|
||||
* Check quota for allocation of this block.
|
||||
*/
|
||||
if (inode) {
|
||||
int ret = dquot_alloc_block(inode, 1);
|
||||
|
||||
if (ret) {
|
||||
mutex_unlock(&sbi->s_alloc_mutex);
|
||||
*err = ret;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
newblock = bit + (block_group << (sb->s_blocksize_bits + 3)) -
|
||||
(sizeof(struct spaceBitmapDesc) << 3);
|
||||
|
||||
|
@ -401,10 +377,6 @@ static void udf_table_free_blocks(struct super_block *sb,
|
|||
}
|
||||
|
||||
iinfo = UDF_I(table);
|
||||
/* We do this up front - There are some error conditions that
|
||||
could occure, but.. oh well */
|
||||
if (inode)
|
||||
dquot_free_block(inode, count);
|
||||
udf_add_free_space(sb, sbi->s_partition, count);
|
||||
|
||||
start = bloc->logicalBlockNum + offset;
|
||||
|
@ -649,10 +621,7 @@ static int udf_table_prealloc_blocks(struct super_block *sb,
|
|||
epos.offset -= adsize;
|
||||
|
||||
alloc_count = (elen >> sb->s_blocksize_bits);
|
||||
if (inode && dquot_prealloc_block(inode,
|
||||
alloc_count > block_count ? block_count : alloc_count))
|
||||
alloc_count = 0;
|
||||
else if (alloc_count > block_count) {
|
||||
if (alloc_count > block_count) {
|
||||
alloc_count = block_count;
|
||||
eloc.logicalBlockNum += alloc_count;
|
||||
elen -= (alloc_count << sb->s_blocksize_bits);
|
||||
|
@ -752,14 +721,6 @@ static int udf_table_new_block(struct super_block *sb,
|
|||
newblock = goal_eloc.logicalBlockNum;
|
||||
goal_eloc.logicalBlockNum++;
|
||||
goal_elen -= sb->s_blocksize;
|
||||
if (inode) {
|
||||
*err = dquot_alloc_block(inode, 1);
|
||||
if (*err) {
|
||||
brelse(goal_epos.bh);
|
||||
mutex_unlock(&sbi->s_alloc_mutex);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (goal_elen)
|
||||
udf_write_aext(table, &goal_epos, &goal_eloc, goal_elen, 1);
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
#include <linux/errno.h>
|
||||
#include <linux/smp_lock.h>
|
||||
#include <linux/pagemap.h>
|
||||
#include <linux/quotaops.h>
|
||||
#include <linux/buffer_head.h>
|
||||
#include <linux/aio.h>
|
||||
#include <linux/smp_lock.h>
|
||||
|
@ -219,7 +218,7 @@ const struct file_operations udf_file_operations = {
|
|||
.read = do_sync_read,
|
||||
.aio_read = generic_file_aio_read,
|
||||
.unlocked_ioctl = udf_ioctl,
|
||||
.open = dquot_file_open,
|
||||
.open = generic_file_open,
|
||||
.mmap = generic_file_mmap,
|
||||
.write = do_sync_write,
|
||||
.aio_write = udf_file_aio_write,
|
||||
|
@ -229,29 +228,6 @@ const struct file_operations udf_file_operations = {
|
|||
.llseek = generic_file_llseek,
|
||||
};
|
||||
|
||||
int udf_setattr(struct dentry *dentry, struct iattr *iattr)
|
||||
{
|
||||
struct inode *inode = dentry->d_inode;
|
||||
int error;
|
||||
|
||||
error = inode_change_ok(inode, iattr);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (is_quota_modification(inode, iattr))
|
||||
dquot_initialize(inode);
|
||||
|
||||
if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) ||
|
||||
(iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) {
|
||||
error = dquot_transfer(inode, iattr);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
|
||||
return inode_setattr(inode, iattr);
|
||||
}
|
||||
|
||||
const struct inode_operations udf_file_inode_operations = {
|
||||
.truncate = udf_truncate,
|
||||
.setattr = udf_setattr,
|
||||
};
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
|
||||
#include "udfdecl.h"
|
||||
#include <linux/fs.h>
|
||||
#include <linux/quotaops.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
|
@ -32,13 +31,6 @@ void udf_free_inode(struct inode *inode)
|
|||
struct super_block *sb = inode->i_sb;
|
||||
struct udf_sb_info *sbi = UDF_SB(sb);
|
||||
|
||||
/*
|
||||
* Note: we must free any quota before locking the superblock,
|
||||
* as writing the quota to disk may need the lock as well.
|
||||
*/
|
||||
dquot_free_inode(inode);
|
||||
dquot_drop(inode);
|
||||
|
||||
clear_inode(inode);
|
||||
|
||||
mutex_lock(&sbi->s_alloc_mutex);
|
||||
|
@ -61,7 +53,7 @@ struct inode *udf_new_inode(struct inode *dir, int mode, int *err)
|
|||
struct super_block *sb = dir->i_sb;
|
||||
struct udf_sb_info *sbi = UDF_SB(sb);
|
||||
struct inode *inode;
|
||||
int block, ret;
|
||||
int block;
|
||||
uint32_t start = UDF_I(dir)->i_location.logicalBlockNum;
|
||||
struct udf_inode_info *iinfo;
|
||||
struct udf_inode_info *dinfo = UDF_I(dir);
|
||||
|
@ -146,17 +138,6 @@ struct inode *udf_new_inode(struct inode *dir, int mode, int *err)
|
|||
insert_inode_hash(inode);
|
||||
mark_inode_dirty(inode);
|
||||
|
||||
dquot_initialize(inode);
|
||||
ret = dquot_alloc_inode(inode);
|
||||
if (ret) {
|
||||
dquot_drop(inode);
|
||||
inode->i_flags |= S_NOQUOTA;
|
||||
inode->i_nlink = 0;
|
||||
iput(inode);
|
||||
*err = ret;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*err = 0;
|
||||
return inode;
|
||||
}
|
||||
|
|
|
@ -36,7 +36,6 @@
|
|||
#include <linux/pagemap.h>
|
||||
#include <linux/buffer_head.h>
|
||||
#include <linux/writeback.h>
|
||||
#include <linux/quotaops.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/crc-itu-t.h>
|
||||
|
||||
|
@ -71,9 +70,6 @@ static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int);
|
|||
|
||||
void udf_delete_inode(struct inode *inode)
|
||||
{
|
||||
if (!is_bad_inode(inode))
|
||||
dquot_initialize(inode);
|
||||
|
||||
truncate_inode_pages(&inode->i_data, 0);
|
||||
|
||||
if (is_bad_inode(inode))
|
||||
|
@ -113,7 +109,6 @@ void udf_clear_inode(struct inode *inode)
|
|||
(unsigned long long)iinfo->i_lenExtents);
|
||||
}
|
||||
|
||||
dquot_drop(inode);
|
||||
kfree(iinfo->i_ext.i_data);
|
||||
iinfo->i_ext.i_data = NULL;
|
||||
}
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#include <linux/errno.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/quotaops.h>
|
||||
#include <linux/smp_lock.h>
|
||||
#include <linux/buffer_head.h>
|
||||
#include <linux/sched.h>
|
||||
|
@ -563,8 +562,6 @@ static int udf_create(struct inode *dir, struct dentry *dentry, int mode,
|
|||
int err;
|
||||
struct udf_inode_info *iinfo;
|
||||
|
||||
dquot_initialize(dir);
|
||||
|
||||
lock_kernel();
|
||||
inode = udf_new_inode(dir, mode, &err);
|
||||
if (!inode) {
|
||||
|
@ -617,8 +614,6 @@ static int udf_mknod(struct inode *dir, struct dentry *dentry, int mode,
|
|||
if (!old_valid_dev(rdev))
|
||||
return -EINVAL;
|
||||
|
||||
dquot_initialize(dir);
|
||||
|
||||
lock_kernel();
|
||||
err = -EIO;
|
||||
inode = udf_new_inode(dir, mode, &err);
|
||||
|
@ -664,8 +659,6 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, int mode)
|
|||
struct udf_inode_info *dinfo = UDF_I(dir);
|
||||
struct udf_inode_info *iinfo;
|
||||
|
||||
dquot_initialize(dir);
|
||||
|
||||
lock_kernel();
|
||||
err = -EMLINK;
|
||||
if (dir->i_nlink >= (256 << sizeof(dir->i_nlink)) - 1)
|
||||
|
@ -800,8 +793,6 @@ static int udf_rmdir(struct inode *dir, struct dentry *dentry)
|
|||
struct fileIdentDesc *fi, cfi;
|
||||
struct kernel_lb_addr tloc;
|
||||
|
||||
dquot_initialize(dir);
|
||||
|
||||
retval = -ENOENT;
|
||||
lock_kernel();
|
||||
fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi);
|
||||
|
@ -848,8 +839,6 @@ static int udf_unlink(struct inode *dir, struct dentry *dentry)
|
|||
struct fileIdentDesc cfi;
|
||||
struct kernel_lb_addr tloc;
|
||||
|
||||
dquot_initialize(dir);
|
||||
|
||||
retval = -ENOENT;
|
||||
lock_kernel();
|
||||
fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi);
|
||||
|
@ -904,8 +893,6 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,
|
|||
struct buffer_head *bh;
|
||||
struct udf_inode_info *iinfo;
|
||||
|
||||
dquot_initialize(dir);
|
||||
|
||||
lock_kernel();
|
||||
inode = udf_new_inode(dir, S_IFLNK | S_IRWXUGO, &err);
|
||||
if (!inode)
|
||||
|
@ -1075,8 +1062,6 @@ static int udf_link(struct dentry *old_dentry, struct inode *dir,
|
|||
int err;
|
||||
struct buffer_head *bh;
|
||||
|
||||
dquot_initialize(dir);
|
||||
|
||||
lock_kernel();
|
||||
if (inode->i_nlink >= (256 << sizeof(inode->i_nlink)) - 1) {
|
||||
unlock_kernel();
|
||||
|
@ -1139,9 +1124,6 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry,
|
|||
struct kernel_lb_addr tloc;
|
||||
struct udf_inode_info *old_iinfo = UDF_I(old_inode);
|
||||
|
||||
dquot_initialize(old_dir);
|
||||
dquot_initialize(new_dir);
|
||||
|
||||
lock_kernel();
|
||||
ofi = udf_find_entry(old_dir, &old_dentry->d_name, &ofibh, &ocfi);
|
||||
if (ofi) {
|
||||
|
@ -1387,7 +1369,6 @@ const struct export_operations udf_export_ops = {
|
|||
const struct inode_operations udf_dir_inode_operations = {
|
||||
.lookup = udf_lookup,
|
||||
.create = udf_create,
|
||||
.setattr = udf_setattr,
|
||||
.link = udf_link,
|
||||
.unlink = udf_unlink,
|
||||
.symlink = udf_symlink,
|
||||
|
@ -1400,5 +1381,4 @@ const struct inode_operations udf_symlink_inode_operations = {
|
|||
.readlink = generic_readlink,
|
||||
.follow_link = page_follow_link_light,
|
||||
.put_link = page_put_link,
|
||||
.setattr = udf_setattr,
|
||||
};
|
||||
|
|
|
@ -557,6 +557,7 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options)
|
|||
{
|
||||
struct udf_options uopt;
|
||||
struct udf_sb_info *sbi = UDF_SB(sb);
|
||||
int error = 0;
|
||||
|
||||
uopt.flags = sbi->s_flags;
|
||||
uopt.uid = sbi->s_uid;
|
||||
|
@ -582,17 +583,17 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options)
|
|||
*flags |= MS_RDONLY;
|
||||
}
|
||||
|
||||
if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) {
|
||||
unlock_kernel();
|
||||
return 0;
|
||||
}
|
||||
if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
|
||||
goto out_unlock;
|
||||
|
||||
if (*flags & MS_RDONLY)
|
||||
udf_close_lvid(sb);
|
||||
else
|
||||
udf_open_lvid(sb);
|
||||
|
||||
out_unlock:
|
||||
unlock_kernel();
|
||||
return 0;
|
||||
return error;
|
||||
}
|
||||
|
||||
/* Check Volume Structure Descriptors (ECMA 167 2/9.1) */
|
||||
|
@ -1939,7 +1940,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
|
|||
/* Fill in the rest of the superblock */
|
||||
sb->s_op = &udf_sb_ops;
|
||||
sb->s_export_op = &udf_export_ops;
|
||||
sb->dq_op = NULL;
|
||||
|
||||
sb->s_dirt = 0;
|
||||
sb->s_magic = UDF_SUPER_MAGIC;
|
||||
sb->s_time_gran = 1000;
|
||||
|
|
|
@ -131,7 +131,6 @@ extern int udf_write_fi(struct inode *inode, struct fileIdentDesc *,
|
|||
|
||||
/* file.c */
|
||||
extern long udf_ioctl(struct file *, unsigned int, unsigned long);
|
||||
extern int udf_setattr(struct dentry *dentry, struct iattr *iattr);
|
||||
/* inode.c */
|
||||
extern struct inode *udf_iget(struct super_block *, struct kernel_lb_addr *);
|
||||
extern int udf_sync_inode(struct inode *);
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#include <linux/stat.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/quotaops.h>
|
||||
#include <linux/buffer_head.h>
|
||||
#include <linux/capability.h>
|
||||
#include <linux/bitops.h>
|
||||
|
@ -85,9 +84,6 @@ void ufs_free_fragments(struct inode *inode, u64 fragment, unsigned count)
|
|||
"bit already cleared for fragment %u", i);
|
||||
}
|
||||
|
||||
dquot_free_block(inode, count);
|
||||
|
||||
|
||||
fs32_add(sb, &ucg->cg_cs.cs_nffree, count);
|
||||
uspi->cs_total.cs_nffree += count;
|
||||
fs32_add(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, count);
|
||||
|
@ -195,7 +191,6 @@ do_more:
|
|||
ubh_setblock(UCPI_UBH(ucpi), ucpi->c_freeoff, blkno);
|
||||
if ((UFS_SB(sb)->s_flags & UFS_CG_MASK) == UFS_CG_44BSD)
|
||||
ufs_clusteracct (sb, ucpi, blkno, 1);
|
||||
dquot_free_block(inode, uspi->s_fpb);
|
||||
|
||||
fs32_add(sb, &ucg->cg_cs.cs_nbfree, 1);
|
||||
uspi->cs_total.cs_nbfree++;
|
||||
|
@ -511,7 +506,6 @@ static u64 ufs_add_fragments(struct inode *inode, u64 fragment,
|
|||
struct ufs_cg_private_info * ucpi;
|
||||
struct ufs_cylinder_group * ucg;
|
||||
unsigned cgno, fragno, fragoff, count, fragsize, i;
|
||||
int ret;
|
||||
|
||||
UFSD("ENTER, fragment %llu, oldcount %u, newcount %u\n",
|
||||
(unsigned long long)fragment, oldcount, newcount);
|
||||
|
@ -557,11 +551,6 @@ static u64 ufs_add_fragments(struct inode *inode, u64 fragment,
|
|||
fs32_add(sb, &ucg->cg_frsum[fragsize - count], 1);
|
||||
for (i = oldcount; i < newcount; i++)
|
||||
ubh_clrbit (UCPI_UBH(ucpi), ucpi->c_freeoff, fragno + i);
|
||||
ret = dquot_alloc_block(inode, count);
|
||||
if (ret) {
|
||||
*err = ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
fs32_sub(sb, &ucg->cg_cs.cs_nffree, count);
|
||||
fs32_sub(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, count);
|
||||
|
@ -598,7 +587,6 @@ static u64 ufs_alloc_fragments(struct inode *inode, unsigned cgno,
|
|||
struct ufs_cylinder_group * ucg;
|
||||
unsigned oldcg, i, j, k, allocsize;
|
||||
u64 result;
|
||||
int ret;
|
||||
|
||||
UFSD("ENTER, ino %lu, cgno %u, goal %llu, count %u\n",
|
||||
inode->i_ino, cgno, (unsigned long long)goal, count);
|
||||
|
@ -667,7 +655,6 @@ cg_found:
|
|||
for (i = count; i < uspi->s_fpb; i++)
|
||||
ubh_setbit (UCPI_UBH(ucpi), ucpi->c_freeoff, goal + i);
|
||||
i = uspi->s_fpb - count;
|
||||
dquot_free_block(inode, i);
|
||||
|
||||
fs32_add(sb, &ucg->cg_cs.cs_nffree, i);
|
||||
uspi->cs_total.cs_nffree += i;
|
||||
|
@ -679,11 +666,6 @@ cg_found:
|
|||
result = ufs_bitmap_search (sb, ucpi, goal, allocsize);
|
||||
if (result == INVBLOCK)
|
||||
return 0;
|
||||
ret = dquot_alloc_block(inode, count);
|
||||
if (ret) {
|
||||
*err = ret;
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < count; i++)
|
||||
ubh_clrbit (UCPI_UBH(ucpi), ucpi->c_freeoff, result + i);
|
||||
|
||||
|
@ -718,7 +700,6 @@ static u64 ufs_alloccg_block(struct inode *inode,
|
|||
struct ufs_super_block_first * usb1;
|
||||
struct ufs_cylinder_group * ucg;
|
||||
u64 result, blkno;
|
||||
int ret;
|
||||
|
||||
UFSD("ENTER, goal %llu\n", (unsigned long long)goal);
|
||||
|
||||
|
@ -752,11 +733,6 @@ gotit:
|
|||
ubh_clrblock (UCPI_UBH(ucpi), ucpi->c_freeoff, blkno);
|
||||
if ((UFS_SB(sb)->s_flags & UFS_CG_MASK) == UFS_CG_44BSD)
|
||||
ufs_clusteracct (sb, ucpi, blkno, -1);
|
||||
ret = dquot_alloc_block(inode, uspi->s_fpb);
|
||||
if (ret) {
|
||||
*err = ret;
|
||||
return INVBLOCK;
|
||||
}
|
||||
|
||||
fs32_sub(sb, &ucg->cg_cs.cs_nbfree, 1);
|
||||
uspi->cs_total.cs_nbfree--;
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
*/
|
||||
|
||||
#include <linux/fs.h>
|
||||
#include <linux/quotaops.h>
|
||||
|
||||
#include "ufs_fs.h"
|
||||
#include "ufs.h"
|
||||
|
@ -41,7 +40,7 @@ const struct file_operations ufs_file_operations = {
|
|||
.write = do_sync_write,
|
||||
.aio_write = generic_file_aio_write,
|
||||
.mmap = generic_file_mmap,
|
||||
.open = dquot_file_open,
|
||||
.open = generic_file_open,
|
||||
.fsync = generic_file_fsync,
|
||||
.splice_read = generic_file_splice_read,
|
||||
};
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#include <linux/time.h>
|
||||
#include <linux/stat.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/quotaops.h>
|
||||
#include <linux/buffer_head.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/bitops.h>
|
||||
|
@ -95,9 +94,6 @@ void ufs_free_inode (struct inode * inode)
|
|||
|
||||
is_directory = S_ISDIR(inode->i_mode);
|
||||
|
||||
dquot_free_inode(inode);
|
||||
dquot_drop(inode);
|
||||
|
||||
clear_inode (inode);
|
||||
|
||||
if (ubh_isclr (UCPI_UBH(ucpi), ucpi->c_iusedoff, bit))
|
||||
|
@ -347,21 +343,12 @@ cg_found:
|
|||
|
||||
unlock_super (sb);
|
||||
|
||||
dquot_initialize(inode);
|
||||
err = dquot_alloc_inode(inode);
|
||||
if (err) {
|
||||
dquot_drop(inode);
|
||||
goto fail_without_unlock;
|
||||
}
|
||||
|
||||
UFSD("allocating inode %lu\n", inode->i_ino);
|
||||
UFSD("EXIT\n");
|
||||
return inode;
|
||||
|
||||
fail_remove_inode:
|
||||
unlock_super(sb);
|
||||
fail_without_unlock:
|
||||
inode->i_flags |= S_NOQUOTA;
|
||||
inode->i_nlink = 0;
|
||||
iput(inode);
|
||||
UFSD("EXIT (FAILED): err %d\n", err);
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
#include <linux/smp_lock.h>
|
||||
#include <linux/buffer_head.h>
|
||||
#include <linux/writeback.h>
|
||||
#include <linux/quotaops.h>
|
||||
|
||||
#include "ufs_fs.h"
|
||||
#include "ufs.h"
|
||||
|
@ -910,9 +909,6 @@ void ufs_delete_inode (struct inode * inode)
|
|||
{
|
||||
loff_t old_i_size;
|
||||
|
||||
if (!is_bad_inode(inode))
|
||||
dquot_initialize(inode);
|
||||
|
||||
truncate_inode_pages(&inode->i_data, 0);
|
||||
if (is_bad_inode(inode))
|
||||
goto no_delete;
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
#include <linux/time.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/smp_lock.h>
|
||||
#include <linux/quotaops.h>
|
||||
|
||||
#include "ufs_fs.h"
|
||||
#include "ufs.h"
|
||||
|
@ -86,8 +85,6 @@ static int ufs_create (struct inode * dir, struct dentry * dentry, int mode,
|
|||
|
||||
UFSD("BEGIN\n");
|
||||
|
||||
dquot_initialize(dir);
|
||||
|
||||
inode = ufs_new_inode(dir, mode);
|
||||
err = PTR_ERR(inode);
|
||||
|
||||
|
@ -112,8 +109,6 @@ static int ufs_mknod (struct inode * dir, struct dentry *dentry, int mode, dev_t
|
|||
if (!old_valid_dev(rdev))
|
||||
return -EINVAL;
|
||||
|
||||
dquot_initialize(dir);
|
||||
|
||||
inode = ufs_new_inode(dir, mode);
|
||||
err = PTR_ERR(inode);
|
||||
if (!IS_ERR(inode)) {
|
||||
|
@ -138,8 +133,6 @@ static int ufs_symlink (struct inode * dir, struct dentry * dentry,
|
|||
if (l > sb->s_blocksize)
|
||||
goto out_notlocked;
|
||||
|
||||
dquot_initialize(dir);
|
||||
|
||||
lock_kernel();
|
||||
inode = ufs_new_inode(dir, S_IFLNK | S_IRWXUGO);
|
||||
err = PTR_ERR(inode);
|
||||
|
@ -185,8 +178,6 @@ static int ufs_link (struct dentry * old_dentry, struct inode * dir,
|
|||
return -EMLINK;
|
||||
}
|
||||
|
||||
dquot_initialize(dir);
|
||||
|
||||
inode->i_ctime = CURRENT_TIME_SEC;
|
||||
inode_inc_link_count(inode);
|
||||
atomic_inc(&inode->i_count);
|
||||
|
@ -204,8 +195,6 @@ static int ufs_mkdir(struct inode * dir, struct dentry * dentry, int mode)
|
|||
if (dir->i_nlink >= UFS_LINK_MAX)
|
||||
goto out;
|
||||
|
||||
dquot_initialize(dir);
|
||||
|
||||
lock_kernel();
|
||||
inode_inc_link_count(dir);
|
||||
|
||||
|
@ -250,8 +239,6 @@ static int ufs_unlink(struct inode *dir, struct dentry *dentry)
|
|||
struct page *page;
|
||||
int err = -ENOENT;
|
||||
|
||||
dquot_initialize(dir);
|
||||
|
||||
de = ufs_find_entry(dir, &dentry->d_name, &page);
|
||||
if (!de)
|
||||
goto out;
|
||||
|
@ -296,9 +283,6 @@ static int ufs_rename(struct inode *old_dir, struct dentry *old_dentry,
|
|||
struct ufs_dir_entry *old_de;
|
||||
int err = -ENOENT;
|
||||
|
||||
dquot_initialize(old_dir);
|
||||
dquot_initialize(new_dir);
|
||||
|
||||
old_de = ufs_find_entry(old_dir, &old_dentry->d_name, &old_page);
|
||||
if (!old_de)
|
||||
goto out;
|
||||
|
|
110
fs/ufs/super.c
110
fs/ufs/super.c
|
@ -77,7 +77,6 @@
|
|||
|
||||
#include <linux/errno.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/quotaops.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/stat.h>
|
||||
|
@ -1047,7 +1046,7 @@ magic_found:
|
|||
*/
|
||||
sb->s_op = &ufs_super_ops;
|
||||
sb->s_export_op = &ufs_export_ops;
|
||||
sb->dq_op = NULL; /***/
|
||||
|
||||
sb->s_magic = fs32_to_cpu(sb, usb3->fs_magic);
|
||||
|
||||
uspi->s_sblkno = fs32_to_cpu(sb, usb1->fs_sblkno);
|
||||
|
@ -1437,126 +1436,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)
|
||||
{
|
||||
|
|
|
@ -44,7 +44,6 @@
|
|||
#include <linux/buffer_head.h>
|
||||
#include <linux/blkdev.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/quotaops.h>
|
||||
|
||||
#include "ufs_fs.h"
|
||||
#include "ufs.h"
|
||||
|
@ -516,15 +515,6 @@ int ufs_setattr(struct dentry *dentry, struct iattr *attr)
|
|||
if (error)
|
||||
return error;
|
||||
|
||||
if (is_quota_modification(inode, attr))
|
||||
dquot_initialize(inode);
|
||||
|
||||
if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
|
||||
(ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
|
||||
error = dquot_transfer(inode, attr);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
if (ia_valid & ATTR_SIZE && attr->ia_size != inode->i_size) {
|
||||
loff_t old_i_size = inode->i_size;
|
||||
|
||||
|
|
|
@ -174,8 +174,7 @@ enum {
|
|||
#include <linux/rwsem.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/percpu.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/percpu_counter.h>
|
||||
|
||||
#include <linux/dqblk_xfs.h>
|
||||
#include <linux/dqblk_v1.h>
|
||||
|
@ -254,6 +253,7 @@ enum {
|
|||
|
||||
struct dqstats {
|
||||
int stat[_DQST_DQSTAT_LAST];
|
||||
struct percpu_counter counter[_DQST_DQSTAT_LAST];
|
||||
};
|
||||
|
||||
extern struct dqstats *dqstats_pcpu;
|
||||
|
@ -261,20 +261,12 @@ extern struct dqstats dqstats;
|
|||
|
||||
static inline void dqstats_inc(unsigned int type)
|
||||
{
|
||||
#ifdef CONFIG_SMP
|
||||
per_cpu_ptr(dqstats_pcpu, smp_processor_id())->stat[type]++;
|
||||
#else
|
||||
dqstats.stat[type]++;
|
||||
#endif
|
||||
percpu_counter_inc(&dqstats.counter[type]);
|
||||
}
|
||||
|
||||
static inline void dqstats_dec(unsigned int type)
|
||||
{
|
||||
#ifdef CONFIG_SMP
|
||||
per_cpu_ptr(dqstats_pcpu, smp_processor_id())->stat[type]--;
|
||||
#else
|
||||
dqstats.stat[type]--;
|
||||
#endif
|
||||
percpu_counter_dec(&dqstats.counter[type]);
|
||||
}
|
||||
|
||||
#define DQ_MOD_B 0 /* dquot modified since read */
|
||||
|
@ -332,8 +324,8 @@ struct dquot_operations {
|
|||
|
||||
/* Operations handling requests from userspace */
|
||||
struct quotactl_ops {
|
||||
int (*quota_on)(struct super_block *, int, int, char *, int);
|
||||
int (*quota_off)(struct super_block *, int, int);
|
||||
int (*quota_on)(struct super_block *, int, int, char *);
|
||||
int (*quota_off)(struct super_block *, int);
|
||||
int (*quota_sync)(struct super_block *, int, int);
|
||||
int (*get_info)(struct super_block *, int, struct if_dqinfo *);
|
||||
int (*set_info)(struct super_block *, int, struct if_dqinfo *);
|
||||
|
|
|
@ -53,6 +53,14 @@ int dquot_alloc_inode(const struct inode *inode);
|
|||
int dquot_claim_space_nodirty(struct inode *inode, qsize_t number);
|
||||
void dquot_free_inode(const struct inode *inode);
|
||||
|
||||
int dquot_disable(struct super_block *sb, int type, unsigned int flags);
|
||||
/* Suspend quotas on remount RO */
|
||||
static inline int dquot_suspend(struct super_block *sb, int type)
|
||||
{
|
||||
return dquot_disable(sb, type, DQUOT_SUSPENDED);
|
||||
}
|
||||
int dquot_resume(struct super_block *sb, int type);
|
||||
|
||||
int dquot_commit(struct dquot *dquot);
|
||||
int dquot_acquire(struct dquot *dquot);
|
||||
int dquot_release(struct dquot *dquot);
|
||||
|
@ -61,27 +69,25 @@ int dquot_mark_dquot_dirty(struct dquot *dquot);
|
|||
|
||||
int dquot_file_open(struct inode *inode, struct file *file);
|
||||
|
||||
int vfs_quota_on(struct super_block *sb, int type, int format_id,
|
||||
char *path, int remount);
|
||||
int vfs_quota_enable(struct inode *inode, int type, int format_id,
|
||||
int dquot_quota_on(struct super_block *sb, int type, int format_id,
|
||||
char *path);
|
||||
int dquot_enable(struct inode *inode, int type, int format_id,
|
||||
unsigned int flags);
|
||||
int vfs_quota_on_path(struct super_block *sb, int type, int format_id,
|
||||
int dquot_quota_on_path(struct super_block *sb, int type, int format_id,
|
||||
struct path *path);
|
||||
int vfs_quota_on_mount(struct super_block *sb, char *qf_name,
|
||||
int dquot_quota_on_mount(struct super_block *sb, char *qf_name,
|
||||
int format_id, int type);
|
||||
int vfs_quota_off(struct super_block *sb, int type, int remount);
|
||||
int vfs_quota_disable(struct super_block *sb, int type, unsigned int flags);
|
||||
int vfs_quota_sync(struct super_block *sb, int type, int wait);
|
||||
int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii);
|
||||
int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii);
|
||||
int vfs_get_dqblk(struct super_block *sb, int type, qid_t id,
|
||||
int dquot_quota_off(struct super_block *sb, int type);
|
||||
int dquot_quota_sync(struct super_block *sb, int type, int wait);
|
||||
int dquot_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii);
|
||||
int dquot_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii);
|
||||
int dquot_get_dqblk(struct super_block *sb, int type, qid_t id,
|
||||
struct fs_disk_quota *di);
|
||||
int vfs_set_dqblk(struct super_block *sb, int type, qid_t id,
|
||||
int dquot_set_dqblk(struct super_block *sb, int type, qid_t id,
|
||||
struct fs_disk_quota *di);
|
||||
|
||||
int __dquot_transfer(struct inode *inode, struct dquot **transfer_to);
|
||||
int dquot_transfer(struct inode *inode, struct iattr *iattr);
|
||||
int vfs_dq_quota_on_remount(struct super_block *sb);
|
||||
|
||||
static inline struct mem_dqinfo *sb_dqinfo(struct super_block *sb, int type)
|
||||
{
|
||||
|
@ -148,20 +154,7 @@ static inline unsigned sb_any_quota_active(struct super_block *sb)
|
|||
* Operations supported for diskquotas.
|
||||
*/
|
||||
extern const struct dquot_operations dquot_operations;
|
||||
extern const struct quotactl_ops vfs_quotactl_ops;
|
||||
|
||||
#define sb_dquot_ops (&dquot_operations)
|
||||
#define sb_quotactl_ops (&vfs_quotactl_ops)
|
||||
|
||||
/* Cannot be called inside a transaction */
|
||||
static inline int vfs_dq_off(struct super_block *sb, int remount)
|
||||
{
|
||||
int ret = -ENOSYS;
|
||||
|
||||
if (sb->s_qcop && sb->s_qcop->quota_off)
|
||||
ret = sb->s_qcop->quota_off(sb, -1, remount);
|
||||
return ret;
|
||||
}
|
||||
extern const struct quotactl_ops dquot_quotactl_ops;
|
||||
|
||||
#else
|
||||
|
||||
|
@ -206,12 +199,6 @@ static inline int sb_any_quota_active(struct super_block *sb)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* NO-OP when quota not configured.
|
||||
*/
|
||||
#define sb_dquot_ops (NULL)
|
||||
#define sb_quotactl_ops (NULL)
|
||||
|
||||
static inline void dquot_initialize(struct inode *inode)
|
||||
{
|
||||
}
|
||||
|
@ -229,16 +216,6 @@ static inline void dquot_free_inode(const struct inode *inode)
|
|||
{
|
||||
}
|
||||
|
||||
static inline int vfs_dq_off(struct super_block *sb, int remount)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int vfs_dq_quota_on_remount(struct super_block *sb)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int dquot_transfer(struct inode *inode, struct iattr *iattr)
|
||||
{
|
||||
return 0;
|
||||
|
@ -265,6 +242,22 @@ static inline int dquot_claim_space_nodirty(struct inode *inode, qsize_t number)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline int dquot_disable(struct super_block *sb, int type,
|
||||
unsigned int flags)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int dquot_suspend(struct super_block *sb, int type)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int dquot_resume(struct super_block *sb, int type)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define dquot_file_open generic_file_open
|
||||
|
||||
#endif /* CONFIG_QUOTA */
|
||||
|
|
Загрузка…
Ссылка в новой задаче