summaryrefslogtreecommitdiffstats
path: root/fs/proc/generic.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1998-08-25 09:12:35 +0000
committerRalf Baechle <ralf@linux-mips.org>1998-08-25 09:12:35 +0000
commitc7fc24dc4420057f103afe8fc64524ebc25c5d37 (patch)
tree3682407a599b8f9f03fc096298134cafba1c9b2f /fs/proc/generic.c
parent1d793fade8b063fde3cf275bf1a5c2d381292cd9 (diff)
o Merge with Linux 2.1.116.
o New Newport console code. o New G364 console code.
Diffstat (limited to 'fs/proc/generic.c')
-rw-r--r--fs/proc/generic.c28
1 files changed, 20 insertions, 8 deletions
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index a38481c85..a9b00f1f5 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -154,14 +154,19 @@ proc_file_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
break;
}
- n -= copy_to_user(buf, start, n); /* BUG ??? */
+ /* This is a hack to allow mangling of file pos independent
+ * of actual bytes read. Simply place the data at page,
+ * return the bytes, and set `start' to the desired offset
+ * as an unsigned int. - Paul.Russell@rustcorp.com.au
+ */
+ n -= copy_to_user(buf, start < page ? page : start, n);
if (n == 0) {
if (retval == 0)
retval = -EFAULT;
break;
}
-
- *ppos += n; /* Move down the file */
+
+ *ppos += start < page ? (long)start : n; /* Move down the file */
nbytes -= n;
buf += n;
retval += n;
@@ -255,13 +260,16 @@ struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,
ent->name = ((char *) ent) + sizeof(*ent);
ent->namelen = len;
- if (mode == S_IFDIR) {
+ if (S_ISDIR(mode)) {
+ if ((mode & S_IALLUGO) == 0)
mode |= S_IRUGO | S_IXUGO;
ent->ops = &proc_dyna_dir_inode_operations;
ent->nlink = 2;
- }
- else if (mode == 0) {
- mode = S_IFREG | S_IRUGO;
+ } else {
+ if ((mode & S_IFMT) == 0)
+ mode |= S_IFREG;
+ if ((mode & S_IALLUGO) == 0)
+ mode |= S_IRUGO;
ent->nlink = 1;
}
ent->mode = mode;
@@ -275,7 +283,11 @@ out:
extern void free_proc_entry(struct proc_dir_entry *);
void free_proc_entry(struct proc_dir_entry *de)
{
- kfree(de);
+ int ino = de->low_ino;
+
+ if (ino >= PROC_DYNAMIC_FIRST &&
+ ino < PROC_DYNAMIC_FIRST+PROC_NDYNAMIC)
+ kfree(de);
}
/*