lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [day] [month] [year] [list]
Date:	Thu, 29 Jul 2010 15:50:38 +0200
From:	Lino Sanfilippo <LinoSanfilippo@....de>
To:	linux-kernel@...r.kernel.org
Cc:	tyhicks@...ux.vnet.ibm.com, kirkland@...onical.com,
	viro@...iv.linux.org.uk
Subject: Questions concerning memory mapping in stackable filesystems


Hi,

I am currently working on a stackable filesystem and would like to implement
memory mapping for it. 
I have looked at the ecryptfs way of doing this and wonder if this really
has to be that complicated (create a persistent file for each inode, start 
a kernel thread only to handle requests to open those persistent files, etc.). 

My plan to handle this was to:

- provide a readpage() address_space operation
- provide a writepage() address_space operation
- delegate the fsync() file operation to the lower filesystem

readpage should do:
1. get the lower page via read_cache_page()
2. copy the content of lower page to upper page

writepage should do:
1. get the lower page via grab_cache_page()
2. copy the content of upper page to lower page
3. mark the lower page dirty (dont actually write it)

fsync should do:
call vfs_fsync() for the lower file and dentry to 
actually write the dirty pages to disk. 

(see code samples below)

So my questions are: 

- Are there any circumstances in which this solution wont work? (It _seems_ 
  to work - at least I was able to copy a file via mmap()).

- What else do i have to take into account for implementing memory mapping in
  a stackable filesystem ?

- What is the difference between grab_cache_page(), read_cache_page() and
  page_cache_read()? They all seem to do more or less the same (look into
  the page cache for the requested page and create it if it was not found)


Thx in advance for any hints and comments!

Lino Sanfilippo


static int my_readpage(struct file *file, struct page *page)
{
	...

	lower_page = read_cache_page(lower_inode->i_mapping, page->index,
				     (filler_t *)lower_a_ops->readpage,
				     (void *)lower_file);
	if (IS_ERR(lower_page)) {
		err = PTR_ERR(lower_page);
		lower_page = NULL;
		printk(KERN_ERR "Error reading from page cache.\n");
		goto out;
	}
	wait_on_page_locked(lower_page);

	page_data = (char *)kmap(page);
	if (!page_data) {
		err = -ENOMEM;
		printk(KERN_ERR "Error mapping page.\n");
		goto out;
	}
	lower_page_data = (char *)kmap(lower_page);
	if (!lower_page_data) {
		err = -ENOMEM;
		printk(KERN_ERR "Error mapping lower page.\n");
		goto out;
	}
	memcpy(page_data, lower_page_data, PAGE_CACHE_SIZE);
	kunmap(lower_page);
	kunmap(page);
out:
	if (lower_page)
		page_cache_release(lower_page);

	if (err)
		ClearPageUptodate(page);
	else
		SetPageUptodate(page);

	unlock_page(page);

	return err;
}

static int my_writepage(struct page *page, struct writeback_control *wbc)
{
	...

	lower_page = grab_cache_page(lower_inode->i_mapping, page->index);

	if (!lower_page) {
		// TODO: proper error value
		rv = -ENOMEM;
		goto fail;
	}
	page_data = (char *) kmap(page);
	if (!page_data) {
		rv = -ENOMEM;
		unlock_page(lower_page);
		goto fail;
	}
	lower_page_data = (char *) kmap(lower_page);
	if (!lower_page_data) {
		rv = -ENOMEM;
		kunmap(page);
		unlock_page(lower_page);
		goto fail;
	}
	memcpy(lower_page_data, page_data, PAGE_CACHE_SIZE);
	kunmap(page);
	kunmap(lower_page);

	SetPageDirty(lower_page);
	unlock_page(lower_page);
	
	SetPageUptodate(page);
fail:
	unlock_page(page);

	return rv;
}


static int my_fsync(struct file *file, struct dentry *dentry,
			  int datasync)
{
	...

	/* do actually write lower pages to disc */
	err = vfs_fsync(lower_file, lower_dentry, datasync);
	return err;
}

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ