Commit ad87b375 authored by Jan Kara's avatar Jan Kara Committed by Linus Torvalds

[PATCH] Implement quota reading and writing functions for UFS.

Attached patch adds functions ufs_quota_read() and ufs_quota_write() to the
UFS code.  So quotas for UFS should work again (they were broken by the
quota io redesign).  I don't actually think the patch is too much important
as I'm not sure anybody uses quotas on UFS but we're in the "stable" branch
so just dropping a support did not seem right to me.
Signed-off-by: default avatarJan Kara <jack@suse.cz>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 63858f83
......@@ -1196,6 +1196,11 @@ static void destroy_inodecache(void)
printk(KERN_INFO "ufs_inode_cache: not all structures were freed\n");
}
#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 struct super_operations ufs_super_ops = {
.alloc_inode = ufs_alloc_inode,
.destroy_inode = ufs_destroy_inode,
......@@ -1206,8 +1211,102 @@ static struct super_operations ufs_super_ops = {
.write_super = ufs_write_super,
.statfs = ufs_statfs,
.remount_fs = ufs_remount,
#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;
down(&inode->i_sem);
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)
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);
up(&inode->i_sem);
return len - towrite;
}
#endif
static struct super_block *ufs_get_sb(struct file_system_type *fs_type,
int flags, const char *dev_name, void *data)
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment