From: Takayuki Nagata <tnagata@redhat.com>
To: linux-fsdevel@vger.kernel.org
Cc: viro@zeniv.linux.org.uk, harshula@redhat.com, mmitsuna@redhat.com
Subject: [PATCH] proc: calculate and initialize size of /proc/<PID>/auxv
Date: Wed, 17 Aug 2011 12:19:40 +0900 [thread overview]
Message-ID: <4E4B334C.90000@redhat.com> (raw)
An ls and a wc commands show 0 size for some of /proc/<PID>/*
files, because getattr methods and inode->i_size variables
are not implemented for these files. These files are known
pseudo, but some peoples may need size of the files.
To calculate and return the size of each /proc/<PID>/auxv,
proc_pid_auxv_getattr() is added. It is used when getattr()
system call for the /proc/<PID>/auxv is called.
To initialize inode->i_size of each /proc/<PID>/* file,
isize_initializer member of pid_entry and some macros are
added, and proc_pid_auxv_isize() is added for i_size of
each /proc/<PID>/auxv.
BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=155943
Signed-off-by: Takayuki Nagata <tnagata@redhat.com>
---
fs/proc/base.c | 66 +++++++++++++++++++++++++++++++++++++++++++------------
1 files changed, 51 insertions(+), 15 deletions(-)
diff --git a/fs/proc/base.c b/fs/proc/base.c
index fc5bc27..e45afd3 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -105,33 +105,37 @@ struct pid_entry {
const struct inode_operations *iop;
const struct file_operations *fop;
union proc_op op;
+ loff_t (*isize_initializer)(struct task_struct*);
};
-#define NOD(NAME, MODE, IOP, FOP, OP) { \
+#define NOD(NAME, MODE, IOP, FOP, OP, ISIZE) { \
.name = (NAME), \
.len = sizeof(NAME) - 1, \
.mode = MODE, \
.iop = IOP, \
.fop = FOP, \
.op = OP, \
+ .isize_initializer = ISIZE, \
}
#define DIR(NAME, MODE, iops, fops) \
- NOD(NAME, (S_IFDIR|(MODE)), &iops, &fops, {} )
+ NOD(NAME, (S_IFDIR|(MODE)), &iops, &fops, {}, NULL )
#define LNK(NAME, get_link) \
NOD(NAME, (S_IFLNK|S_IRWXUGO), \
&proc_pid_link_inode_operations, NULL, \
- { .proc_get_link = get_link } )
+ { .proc_get_link = get_link }, NULL )
#define REG(NAME, MODE, fops) \
- NOD(NAME, (S_IFREG|(MODE)), NULL, &fops, {})
+ NOD(NAME, (S_IFREG|(MODE)), NULL, &fops, {}, NULL )
+#define INF_WITH_IOP(NAME, MODE, read, iop, isize) \
+ NOD(NAME, (S_IFREG|(MODE)), \
+ iop, &proc_info_file_operations, \
+ { .proc_read = read }, isize )
#define INF(NAME, MODE, read) \
- NOD(NAME, (S_IFREG|(MODE)), \
- NULL, &proc_info_file_operations, \
- { .proc_read = read } )
+ INF_WITH_IOP(NAME, MODE, read, NULL, NULL )
#define ONE(NAME, MODE, show) \
NOD(NAME, (S_IFREG|(MODE)), \
NULL, &proc_single_file_operations, \
- { .proc_show = show } )
+ { .proc_show = show }, NULL )
/*
* Count the number of hardlinks for the pid_entry table, excluding the .
@@ -309,9 +313,8 @@ out:
return res;
}
-static int proc_pid_auxv(struct task_struct *task, char *buffer)
+inline static int count_mm_saved_auxv(struct mm_struct *mm)
{
- struct mm_struct *mm = mm_for_maps(task);
int res = PTR_ERR(mm);
if (mm && !IS_ERR(mm)) {
unsigned int nwords = 0;
@@ -321,12 +324,43 @@ static int proc_pid_auxv(struct task_struct *task, char *buffer)
res = nwords * sizeof(mm->saved_auxv[0]);
if (res > PAGE_SIZE)
res = PAGE_SIZE;
- memcpy(buffer, mm->saved_auxv, res);
- mmput(mm);
}
return res;
}
+static int proc_pid_auxv(struct task_struct *task, char *buffer)
+{
+ int size;
+ struct mm_struct *mm = get_task_mm(task);
+ size = count_mm_saved_auxv(mm);
+ if (mm) {
+ if(buffer)
+ memcpy(buffer, mm->saved_auxv, size);
+ mmput(mm);
+ }
+ return size;
+}
+
+static loff_t proc_pid_auxv_isize(struct task_struct *task)
+{
+ struct mm_struct *mm = get_task_mm(task);
+ return count_mm_saved_auxv(mm);
+}
+
+static int proc_pid_auxv_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
+{
+ struct inode *inode = dentry->d_inode;
+ struct task_struct *task = get_proc_task(inode);
+ struct mm_struct *mm = get_task_mm(task);
+
+ generic_fillattr(inode, stat);
+ stat->size = count_mm_saved_auxv(mm);
+ return 0;
+}
+
+static struct inode_operations proc_pid_auxv_inode_operations = {
+ .getattr = proc_pid_auxv_getattr,
+};
#ifdef CONFIG_KALLSYMS
/*
@@ -2253,6 +2287,8 @@ static struct dentry *proc_pident_instantiate(struct inode *dir,
ei = PROC_I(inode);
inode->i_mode = p->mode;
+ if (p->isize_initializer)
+ inode->i_size = p->isize_initializer(task);
if (S_ISDIR(inode->i_mode))
inode->i_nlink = 2; /* Use getattr to fix if necessary */
if (p->iop)
@@ -2617,7 +2653,7 @@ static const struct inode_operations proc_self_inode_operations = {
*/
static const struct pid_entry proc_base_stuff[] = {
NOD("self", S_IFLNK|S_IRWXUGO,
- &proc_self_inode_operations, NULL, {}),
+ &proc_self_inode_operations, NULL, {}, NULL),
};
static struct dentry *proc_base_instantiate(struct inode *dir,
@@ -2774,7 +2810,7 @@ static const struct pid_entry tgid_base_stuff[] = {
DIR("net", S_IRUGO|S_IXUGO, proc_net_inode_operations, proc_net_operations),
#endif
REG("environ", S_IRUSR, proc_environ_operations),
- INF("auxv", S_IRUSR, proc_pid_auxv),
+ INF_WITH_IOP("auxv", S_IRUSR, proc_pid_auxv, &proc_pid_auxv_inode_operations, proc_pid_auxv_isize),
ONE("status", S_IRUGO, proc_pid_status),
ONE("personality", S_IRUGO, proc_pid_personality),
INF("limits", S_IRUGO, proc_pid_limits),
@@ -3123,7 +3159,7 @@ static const struct pid_entry tid_base_stuff[] = {
DIR("fdinfo", S_IRUSR|S_IXUSR, proc_fdinfo_inode_operations, proc_fdinfo_operations),
DIR("ns", S_IRUSR|S_IXUGO, proc_ns_dir_inode_operations, proc_ns_dir_operations),
REG("environ", S_IRUSR, proc_environ_operations),
- INF("auxv", S_IRUSR, proc_pid_auxv),
+ INF_WITH_IOP("auxv", S_IRUSR, proc_pid_auxv, &proc_pid_auxv_inode_operations, proc_pid_auxv_isize),
ONE("status", S_IRUGO, proc_pid_status),
ONE("personality", S_IRUGO, proc_pid_personality),
INF("limits", S_IRUGO, proc_pid_limits),
--
1.7.4.4
next reply other threads:[~2011-08-17 3:19 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-08-17 3:19 Takayuki Nagata [this message]
2011-08-17 3:51 ` [PATCH] proc: calculate and initialize size of /proc/<PID>/auxv 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=4E4B334C.90000@redhat.com \
--to=tnagata@redhat.com \
--cc=harshula@redhat.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=mmitsuna@redhat.com \
--cc=viro@zeniv.linux.org.uk \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).