summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjdike <jdike>2003-05-22 15:56:28 +0000
committerjdike <jdike>2003-05-22 15:56:28 +0000
commit0b5428d2356a36c795032a8da0cb8ac21b5dcad8 (patch)
tree31d44cea89151319190ba96972b229ee123bf3f7
parent819f46efd2c1dadb6756eb867ba0e57994813104 (diff)
downloaduml-history-0b5428d2356a36c795032a8da0cb8ac21b5dcad8.tar.gz
Added chroot and append-only options to hostfs.
-rw-r--r--arch/um/fs/hostfs/hostfs.h2
-rw-r--r--arch/um/fs/hostfs/hostfs_kern.c69
-rw-r--r--arch/um/fs/hostfs/hostfs_user.c22
3 files changed, 76 insertions, 17 deletions
diff --git a/arch/um/fs/hostfs/hostfs.h b/arch/um/fs/hostfs/hostfs.h
index e5af1d5..7cf3b5b 100644
--- a/arch/um/fs/hostfs/hostfs.h
+++ b/arch/um/fs/hostfs/hostfs.h
@@ -38,7 +38,7 @@ extern int stat_file(const char *path, int *dev_out,
unsigned long *mtime_out, unsigned long *ctime_out,
int *blksize_out, unsigned long long *blocks_out);
extern int access_file(char *path, int r, int w, int x);
-extern int open_file(char *path, int r, int w);
+extern int open_file(char *path, int r, int w, int append);
extern int file_type(const char *path, int *rdev);
extern void *open_dir(char *path, int *err_out);
extern char *read_dir(void *stream, unsigned long long *pos,
diff --git a/arch/um/fs/hostfs/hostfs_kern.c b/arch/um/fs/hostfs/hostfs_kern.c
index a4615cf..3a50894 100644
--- a/arch/um/fs/hostfs/hostfs_kern.c
+++ b/arch/um/fs/hostfs/hostfs_kern.c
@@ -17,6 +17,7 @@
#include "kern.h"
#include "user_util.h"
#include "2_5compat.h"
+#include "init.h"
#define file_hostfs_i(file) (&(file)->f_dentry->d_inode->u.hostfs_i)
@@ -29,8 +30,9 @@ struct dentry_operations hostfs_dentry_ops = {
.d_delete = hostfs_d_delete,
};
-/* Not changed */
+/* Changed in hostfs_args before the kernel starts running */
static char *root_ino = "/";
+static int append = 0;
#define HOSTFS_SUPER_MAGIC 0x00c0ffee
@@ -38,6 +40,43 @@ static struct inode_operations hostfs_iops;
static struct inode_operations hostfs_dir_iops;
static struct address_space_operations hostfs_link_aops;
+static int __init hostfs_args(char *options, int *add)
+{
+ char *ptr;
+
+ ptr = strchr(options, ',');
+ if(ptr != NULL)
+ *ptr++ = '\0';
+ if(*options != '\0')
+ root_ino = options;
+
+ options = ptr;
+ while(options){
+ ptr = strchr(options, ',');
+ if(ptr != NULL)
+ *ptr++ = '\0';
+ if(*options != '\0'){
+ if(!strcmp(options, "append"))
+ append = 1;
+ else printf("hostfs_args - unsupported option - %s\n",
+ options);
+ }
+ options = ptr;
+ }
+ return(0);
+}
+
+__uml_setup("hostfs=", hostfs_args,
+"hostfs=<root dir>,<flags>,...\n"
+" This is used to set hostfs parameters. The root directory argument\n"
+" is used to confine all hostfs mounts to within the specified directory\n"
+" tree on the host. If this isn't specified, then a user inside UML can\n"
+" mount anything on the host that's accessible to the user that's running\n"
+" it.\n"
+" The only flag currently supported is 'append', which specifies that all\n"
+" files opened by hostfs will be opened in append mode.\n\n"
+);
+
static char *dentry_name(struct dentry *dentry, int extra)
{
struct dentry *parent;
@@ -274,7 +313,7 @@ int hostfs_file_open(struct inode *ino, struct file *file)
if(name == NULL)
return(-ENOMEM);
- fd = open_file(name, r, w);
+ fd = open_file(name, r, w, append);
kfree(name);
if(fd < 0) return(fd);
file_hostfs_i(file)->fd = fd;
@@ -363,6 +402,8 @@ int hostfs_readpage(struct file *file, struct page *page)
PAGE_CACHE_SIZE);
if(err < 0) goto out;
+ memset(&buffer[err], 0, PAGE_CACHE_SIZE - err);
+
flush_dcache_page(page);
SetPageUptodate(page);
if (PageError(page)) ClearPageError(page);
@@ -424,6 +465,7 @@ int hostfs_commit_write(struct file *file, struct page *page, unsigned from,
static struct address_space_operations hostfs_aops = {
.writepage = hostfs_writepage,
.readpage = hostfs_readpage,
+/* .set_page_dirty = __set_page_dirty_nobuffers, */
.prepare_write = hostfs_prepare_write,
.commit_write = hostfs_commit_write
};
@@ -497,7 +539,7 @@ int hostfs_create(struct inode *dir, struct dentry *dentry, int mode)
{
struct inode *inode;
char *name;
- int error;
+ int error, fd;
inode = get_inode(dir->i_sb, dentry, &error);
if(error) return(error);
@@ -506,16 +548,21 @@ int hostfs_create(struct inode *dir, struct dentry *dentry, int mode)
iput(inode);
return(-ENOMEM);
}
- error = file_create(name,
- mode & S_IRUSR, mode & S_IWUSR, mode & S_IXUSR,
- mode & S_IRGRP, mode & S_IWGRP, mode & S_IXGRP,
- mode & S_IROTH, mode & S_IWOTH, mode & S_IXOTH);
- if(!error) error = read_name(inode, name);
+ fd = file_create(name,
+ mode & S_IRUSR, mode & S_IWUSR, mode & S_IXUSR,
+ mode & S_IRGRP, mode & S_IWGRP, mode & S_IXGRP,
+ mode & S_IROTH, mode & S_IWOTH, mode & S_IXOTH);
+ if(fd < 0)
+ error = fd;
+ else error = read_name(inode, name);
+
kfree(name);
if(error){
iput(inode);
return(error);
}
+ inode->u.hostfs_i.fd = fd;
+ inode->u.hostfs_i.mode = FMODE_READ | FMODE_WRITE;
d_instantiate(dentry, inode);
return(0);
}
@@ -580,6 +627,9 @@ int hostfs_unlink(struct inode *ino, struct dentry *dentry)
int err;
if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
+ if(append)
+ return(-EPERM);
+
err = unlink_file(file);
kfree(file);
return(err);
@@ -687,6 +737,9 @@ int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
struct hostfs_iattr attrs;
char *name;
int err;
+
+ if(append)
+ attr->ia_valid &= ~ATTR_SIZE;
attrs.ia_valid = 0;
if(attr->ia_valid & ATTR_MODE){
diff --git a/arch/um/fs/hostfs/hostfs_user.c b/arch/um/fs/hostfs/hostfs_user.c
index 97e40ac..48f3e4e 100644
--- a/arch/um/fs/hostfs/hostfs_user.c
+++ b/arch/um/fs/hostfs/hostfs_user.c
@@ -75,14 +75,20 @@ int access_file(char *path, int r, int w, int x)
else return(0);
}
-int open_file(char *path, int r, int w)
+int open_file(char *path, int r, int w, int append)
{
int mode = 0, fd;
- if(r && !w) mode = O_RDONLY;
- else if(!r && w) mode = O_WRONLY;
- else if(r && w) mode = O_RDWR;
+ if(r && !w)
+ mode = O_RDONLY;
+ else if(!r && w)
+ mode = O_WRONLY;
+ else if(r && w)
+ mode = O_RDWR;
else panic("Impossible mode in open_file");
+
+ if(append)
+ mode |= O_APPEND;
fd = open64(path, mode);
if(fd < 0) return(-errno);
else return(fd);
@@ -167,10 +173,10 @@ int file_create(char *name, int ur, int uw, int ux, int gr,
mode |= or ? S_IROTH : 0;
mode |= ow ? S_IWOTH : 0;
mode |= ox ? S_IXOTH : 0;
- fd = open64(name, O_CREAT, mode);
- if(fd < 0) return(-errno);
- close(fd);
- return(0);
+ fd = open64(name, O_CREAT | O_RDWR, mode);
+ if(fd < 0)
+ return(-errno);
+ return(fd);
}
int set_attr(const char *file, struct hostfs_iattr *attrs)