From: Tony Luck <tony.luck@intel.com>
To: Al Viro <viro@zeniv.linux.org.uk>
Cc: Xiaotian Feng <xtfeng@gmail.com>,
Linus Torvalds <torvalds@linux-foundation.org>,
linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org
Subject: Some fixes for pstore (Was Re: [git pull] mnt_devname queue)
Date: Thu, 17 Mar 2011 14:35:42 -0700 [thread overview]
Message-ID: <4d827eae305473e2bf@agluck-desktop.sc.intel.com> (raw)
In-Reply-To: <20110317104434.GB22723@ZenIV.linux.org.uk>
Al,
I haven't got all your suggestions implemented yet - but thought I'd do
a quick direction check to see if I understood your e-mail.
Fixes below:
1) Change from ->get_sb() to ->mount()
2) Use mount_single() instead of mount_nodev()
3) Pulled in ramfs_get_inode() & trimmed to what I need for pstore
4) Drop the ugly pstore_writefile() Just save data using kmalloc() and
provide a pstore_file_read() that uses simple_read_from_buffer().
Still todo:
1) Handle multiple mounts
2) Use simple_pin_fs/mntput to prevent races
3) Move cleanup from unlink to evict_inode
4) Stop it from saving dmesg on a clean "reboot" [!! Not sure when it started doing this !!]
-Tony
---
diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c
index 549d245..7d848b1 100644
--- a/fs/pstore/inode.c
+++ b/fs/pstore/inode.c
@@ -40,9 +40,29 @@
struct pstore_private {
u64 id;
int (*erase)(u64);
+ ssize_t size;
+ char data[];
};
-#define pstore_get_inode ramfs_get_inode
+static int pstore_file_open(struct inode *inode, struct file *file)
+{
+ file->private_data = inode->i_private;
+ return 0;
+}
+
+static ssize_t pstore_file_read(struct file *file, char __user *userbuf,
+ size_t count, loff_t *ppos)
+{
+ struct pstore_private *ps = file->private_data;
+
+ return simple_read_from_buffer(userbuf, count, ppos, ps->data, ps->size);
+}
+
+static const struct file_operations pstore_file_operations = {
+ .open = pstore_file_open,
+ .read = pstore_file_read,
+ .llseek = default_llseek,
+};
/*
* When a file is unlinked from our file system we call the
@@ -63,6 +83,30 @@ static const struct inode_operations pstore_dir_inode_operations = {
.unlink = pstore_unlink,
};
+static struct inode *pstore_get_inode(struct super_block *sb,
+ const struct inode *dir, int mode, dev_t dev)
+{
+ struct inode *inode = new_inode(sb);
+
+ if (inode) {
+ inode->i_ino = get_next_ino();
+ inode->i_uid = inode->i_gid = 0;
+ inode->i_mode = mode;
+ inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+ switch (mode & S_IFMT) {
+ case S_IFREG:
+ inode->i_fop = &pstore_file_operations;
+ break;
+ case S_IFDIR:
+ inode->i_op = &pstore_dir_inode_operations;
+ inode->i_fop = &simple_dir_operations;
+ inc_nlink(inode);
+ break;
+ }
+ }
+ return inode;
+}
+
static const struct super_operations pstore_ops = {
.statfs = simple_statfs,
.drop_inode = generic_delete_inode,
@@ -70,37 +114,10 @@ static const struct super_operations pstore_ops = {
};
static struct super_block *pstore_sb;
-static struct vfsmount *pstore_mnt;
int pstore_is_mounted(void)
{
- return pstore_mnt != NULL;
-}
-
-/*
- * Set up a file structure as if we had opened this file and
- * write our data to it.
- */
-static int pstore_writefile(struct inode *inode, struct dentry *dentry,
- char *data, size_t size)
-{
- struct file f;
- ssize_t n;
- mm_segment_t old_fs = get_fs();
-
- memset(&f, '0', sizeof f);
- f.f_mapping = inode->i_mapping;
- f.f_path.dentry = dentry;
- f.f_path.mnt = pstore_mnt;
- f.f_pos = 0;
- f.f_op = inode->i_fop;
- set_fs(KERNEL_DS);
- n = do_sync_write(&f, data, size, &f.f_pos);
- set_fs(old_fs);
-
- fsnotify_modify(&f);
-
- return n == size;
+ return pstore_sb != NULL;
}
/*
@@ -123,8 +140,7 @@ int pstore_mkfile(enum pstore_type_id type, char *psname, u64 id,
inode = pstore_get_inode(pstore_sb, root->d_inode, S_IFREG | 0444, 0);
if (!inode)
goto fail;
- inode->i_uid = inode->i_gid = 0;
- private = kmalloc(sizeof *private, GFP_KERNEL);
+ private = kmalloc(sizeof *private + size, GFP_KERNEL);
if (!private)
goto fail_alloc;
private->id = id;
@@ -156,8 +172,8 @@ int pstore_mkfile(enum pstore_type_id type, char *psname, u64 id,
mutex_unlock(&root->d_inode->i_mutex);
- if (!pstore_writefile(inode, dentry, data, size))
- goto fail_write;
+ memcpy(private->data, data, size);
+ inode->i_size = private->size = size;
inode->i_private = private;
@@ -166,15 +182,6 @@ int pstore_mkfile(enum pstore_type_id type, char *psname, u64 id,
return 0;
-fail_write:
- kfree(private);
- inode->i_nlink--;
- mutex_lock(&root->d_inode->i_mutex);
- d_delete(dentry);
- dput(dentry);
- mutex_unlock(&root->d_inode->i_mutex);
- goto fail;
-
fail_lockedalloc:
mutex_unlock(&root->d_inode->i_mutex);
kfree(private);
@@ -225,32 +232,27 @@ fail:
return err;
}
-static int pstore_get_sb(struct file_system_type *fs_type,
- int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *pstore_mount(struct file_system_type *fs_type,
+ int flags, const char *dev_name, void *data)
{
struct dentry *root;
- root = mount_nodev(fs_type, flags, data, pstore_fill_super);
+ root = mount_single(fs_type, flags, data, pstore_fill_super);
if (IS_ERR(root))
- return -ENOMEM;
-
- mnt->mnt_root = root;
- mnt->mnt_sb = root->d_sb;
- pstore_mnt = mnt;
+ return root;
- return 0;
+ return root;
}
static void pstore_kill_sb(struct super_block *sb)
{
kill_litter_super(sb);
pstore_sb = NULL;
- pstore_mnt = NULL;
}
static struct file_system_type pstore_fs_type = {
.name = "pstore",
- .get_sb = pstore_get_sb,
+ .mount = pstore_mount,
.kill_sb = pstore_kill_sb,
};
next prev parent reply other threads:[~2011-03-17 21:35 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-03-16 23:56 [git pull] mnt_devname queue Al Viro
2011-03-17 5:45 ` Xiaotian Feng
2011-03-17 5:45 ` Xiaotian Feng
2011-03-17 7:23 ` Al Viro
2011-03-17 7:28 ` Xiaotian Feng
2011-03-17 10:44 ` Al Viro
2011-03-17 19:08 ` Tony Luck
2011-03-17 21:35 ` Tony Luck [this message]
2011-03-17 22:42 ` Some fixes for pstore (Was Re: [git pull] mnt_devname queue) Al Viro
2011-03-17 22:48 ` Tony Luck
2011-03-17 22:48 ` Tony Luck
2011-03-17 22:56 ` Al Viro
2011-03-18 18:44 ` pstore: fix leaking ->i_private Luck, Tony
2011-03-18 18:49 ` Christoph Hellwig
2011-03-18 18:55 ` Tony Luck
2011-03-18 18:55 ` Tony Luck
2011-03-18 22:33 ` pstore: use mount option instead sysfs to tweak kmsg_bytes Luck, Tony
2011-03-18 18:57 ` pstore: fix leaking ->i_private Al Viro
2011-03-17 23:29 ` Some fixes for pstore (Was Re: [git pull] mnt_devname queue) Tony Luck
2011-03-18 0:07 ` Al Viro
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4d827eae305473e2bf@agluck-desktop.sc.intel.com \
--to=tony.luck@intel.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=torvalds@linux-foundation.org \
--cc=viro@zeniv.linux.org.uk \
--cc=xtfeng@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.