mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
o Sync up of todays changes .... nothing very important
This commit is contained in:
parent
8402493a28
commit
257ef2ba58
@ -24,16 +24,41 @@
|
|||||||
|
|
||||||
static ssize_t dmfs_suspend_read(struct file *file, char *buf, size_t size, loff_t *pos)
|
static ssize_t dmfs_suspend_read(struct file *file, char *buf, size_t size, loff_t *pos)
|
||||||
{
|
{
|
||||||
down(&inode->i_sem);
|
struct inode *inode = file->f_dentry->d_parent->d_inode;
|
||||||
|
struct mapped_device *md = (struct mapped_device *)inode->u.generic_ip;
|
||||||
|
|
||||||
up(&inode->i_sem);
|
char content[2] = { '0', '\n' };
|
||||||
|
|
||||||
|
if (size > 2)
|
||||||
|
size = 2;
|
||||||
|
|
||||||
|
if (test_bit(DM_ACTIVE, &md->state))
|
||||||
|
content[0] = '1';
|
||||||
|
|
||||||
|
if (copy_to_user(buf, content, size))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t dmfs_suspend_write(struct file *file, const char *buf, size_t size, loff_t *pos)
|
static ssize_t dmfs_suspend_write(struct file *file, const char *buf, size_t size, loff_t *pos)
|
||||||
{
|
{
|
||||||
down(&inode->i_sem);
|
struct inode *inode = file->f_dentry->d_inode;
|
||||||
|
char cmd;
|
||||||
|
|
||||||
up(&inode->i_sem);
|
if (size == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
size = 1;
|
||||||
|
if (copy_from_user(&cmd, buf, size))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
if (cmd != '0' && cmd != '1')
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* do suspend or unsuspend */
|
||||||
|
|
||||||
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dmfs_suspend_sync(struct file *file, struct dentry *dentry, int datasync)
|
static int dmfs_suspend_sync(struct file *file, struct dentry *dentry, int datasync)
|
||||||
@ -42,10 +67,8 @@ static int dmfs_suspend_sync(struct file *file, struct dentry *dentry, int datas
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct dm_table_file_operations = {
|
static struct dm_table_file_operations = {
|
||||||
/* llseek: generic_file_llseek, */
|
|
||||||
read: dmfs_suspend_read,
|
read: dmfs_suspend_read,
|
||||||
write: dmfs_suspend_write,
|
write: dmfs_suspend_write,
|
||||||
open: dmfs_suspend_open,
|
|
||||||
fsync: dmfs_suspend_sync,
|
fsync: dmfs_suspend_sync,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -21,18 +21,179 @@
|
|||||||
|
|
||||||
#include <linux/config.h>
|
#include <linux/config.h>
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
|
#include <linux/parser.h>
|
||||||
|
#include "dm.h"
|
||||||
|
|
||||||
|
|
||||||
|
static int dmfs_parse_line(struct dmfs_table *t, char *str)
|
||||||
|
{
|
||||||
|
char *p = str;
|
||||||
|
const char *delim = " \t";
|
||||||
|
const char *tok;
|
||||||
|
offset_t start, size, high;
|
||||||
|
void *context;
|
||||||
|
struct target_type *ttype;
|
||||||
|
|
||||||
|
tok = strsep(&p, delim);
|
||||||
|
if (!tok)
|
||||||
|
return -1;
|
||||||
|
start = simple_strtoul(tok, NULL, 10);
|
||||||
|
|
||||||
|
tok = strsep(&p, delim);
|
||||||
|
if (!tok)
|
||||||
|
return -1;
|
||||||
|
size = simple_strtoul(tok, NULL, 10);
|
||||||
|
|
||||||
|
tok = strsep(&p, delim);
|
||||||
|
if (!tok)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
ttype = dm_get_target_type(tok);
|
||||||
|
if (ttype) {
|
||||||
|
context = ttype->ctr(t, start, size, p);
|
||||||
|
if (!IS_ERR(context)) {
|
||||||
|
high = start + (size - 1);
|
||||||
|
if (dm_table_add_target(t, high, ttype, context) == 0)
|
||||||
|
return 0;
|
||||||
|
ttype->dtr(t, context);
|
||||||
|
}
|
||||||
|
dm_put_target_type(ttype);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dmfs_copy(char *dst, int dstlen, char *src, int srclen, int *flag)
|
||||||
|
{
|
||||||
|
int copied = 0;
|
||||||
|
|
||||||
|
while(dstlen && srclen) {
|
||||||
|
*dst = *src++;
|
||||||
|
copied++;
|
||||||
|
if (*dst == '\n')
|
||||||
|
goto end_of_line;
|
||||||
|
dst++;
|
||||||
|
dstlen--;
|
||||||
|
srclen--;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
return copied;
|
||||||
|
end_of_line:
|
||||||
|
*flag = 1;
|
||||||
|
*dst = 0;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dmfs_parse_page(struct dm_table *t, char *buf, int len, char *tmp, unsigned long *tmpl)
|
||||||
|
{
|
||||||
|
int copied;
|
||||||
|
|
||||||
|
do {
|
||||||
|
int flag = 0;
|
||||||
|
copied = dmfs_copy(tmp + *tmpl, PAGE_SIZE - *tmpl - 1, buf, len, &flag);
|
||||||
|
buf += copied;
|
||||||
|
len -= copied;
|
||||||
|
if (*tmpl + copied == PAGE_SIZE - 1)
|
||||||
|
return -1;
|
||||||
|
*tmpl = copied;
|
||||||
|
if (flag) {
|
||||||
|
if (dmfs_parse_line(t, tmp))
|
||||||
|
return -1;
|
||||||
|
*tmpl = 0;
|
||||||
|
}
|
||||||
|
} while(len > 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct dm_table *dmfs_parse(struct inode *inode)
|
||||||
|
{
|
||||||
|
struct address_space *mapping = inode->i_mapping;
|
||||||
|
unsigned long index = 0;
|
||||||
|
unsigned long offset = 0;
|
||||||
|
unsigned long end_index, end_offset;
|
||||||
|
unsigned long page;
|
||||||
|
unsigned long rem = 0;
|
||||||
|
struct dm_table *t;
|
||||||
|
struct page *pg, **hash;
|
||||||
|
|
||||||
|
if (inode->i_size == 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
page = __get_free_page(GFP_KERNEL);
|
||||||
|
|
||||||
|
if (!page)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
t = dm_create_table();
|
||||||
|
if (!t) {
|
||||||
|
free_page(page);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
down(&inode->i_sem);
|
||||||
|
end_index = inode->i_size >> PAGE_CACHE_SIZE;
|
||||||
|
end_offset = inode->i_size & (PAGE_CAHE_SIZE - 1);
|
||||||
|
|
||||||
|
do {
|
||||||
|
unsigned long end = (index == end_index) ? end_offset : PAGE_CACHE_SIZE;
|
||||||
|
hash = page_hash(mapping, index);
|
||||||
|
|
||||||
|
spin_lock(&pagecache_lock);
|
||||||
|
pg = __find_page_nolock(mapping, index, *hash);
|
||||||
|
if (pg)
|
||||||
|
page_cache_get(pg);
|
||||||
|
spin_unlock(&pagecache_lock);
|
||||||
|
|
||||||
|
if (pg) {
|
||||||
|
if (!Page_Uptodate(pg))
|
||||||
|
goto broken;
|
||||||
|
|
||||||
|
if (dmfs_parse_page(t, pg, end, (char *)page, &rem))
|
||||||
|
goto parse_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
page_cache_release(pg);
|
||||||
|
index++;
|
||||||
|
} while(index != end_index);
|
||||||
|
|
||||||
|
up(&inode->i_sem);
|
||||||
|
|
||||||
|
free_page(page);
|
||||||
|
if (dm_table_complete(t) == 0)
|
||||||
|
return t;
|
||||||
|
|
||||||
|
dm_put_table(t);
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
broken:
|
||||||
|
up(&inode->i_sem);
|
||||||
|
printk(KERN_ERR "dmfs_parse: Page not uptodate\n");
|
||||||
|
free_page(page);
|
||||||
|
dm_put_table(t);
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
parse_error:
|
||||||
|
up(&inode->i_sem);
|
||||||
|
printk(KERN_ERR "dmfs_parse: Parse error\n");
|
||||||
|
free_page(page);
|
||||||
|
dm_put_table(t);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static int dmfs_release(struct inode *inode, struct file *f)
|
static int dmfs_release(struct inode *inode, struct file *f)
|
||||||
{
|
{
|
||||||
struct dm_table *table;
|
struct dm_table *table;
|
||||||
|
|
||||||
/* FIXME: we should lock the inode to
|
|
||||||
prevent someone else opening it while
|
|
||||||
we are parsing */
|
|
||||||
|
|
||||||
if (!(f->f_mode & S_IWUGO))
|
if (!(f->f_mode & S_IWUGO))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
table = dmfs_parse(inode);
|
||||||
|
|
||||||
|
if (table) {
|
||||||
|
dm_put_table((struct dm_table *)inode->u.generic_ip);
|
||||||
|
inode->u.generic_ip = table;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dmfs_readpage(struct file *file, struct page *page)
|
static int dmfs_readpage(struct file *file, struct page *page)
|
||||||
@ -95,7 +256,6 @@ static struct dm_table_file_operations = {
|
|||||||
llseek: generic_file_llseek,
|
llseek: generic_file_llseek,
|
||||||
read: generic_file_read,
|
read: generic_file_read,
|
||||||
write: generic_file_write,
|
write: generic_file_write,
|
||||||
mmap: generic_file_mmap,
|
|
||||||
fsync: dmfs_table_sync,
|
fsync: dmfs_table_sync,
|
||||||
release: dmfs_release,
|
release: dmfs_release,
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user