Blame view
fs/hostfs/hostfs_kern.c
20.6 KB
1da177e4c Linux-2.6.12-rc2 |
1 |
/* |
f1adc05e7 uml: hostfs style... |
2 |
* Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) |
1da177e4c Linux-2.6.12-rc2 |
3 4 5 6 7 |
* Licensed under the GPL * * Ported the filesystem routines to 2.5. * 2003-02-10 Petr Baudis <pasky@ucw.cz> */ |
1da177e4c Linux-2.6.12-rc2 |
8 |
#include <linux/fs.h> |
1da177e4c Linux-2.6.12-rc2 |
9 |
#include <linux/module.h> |
84b3db04c uml: fix hostfs s... |
10 |
#include <linux/mm.h> |
1da177e4c Linux-2.6.12-rc2 |
11 |
#include <linux/pagemap.h> |
1da177e4c Linux-2.6.12-rc2 |
12 |
#include <linux/statfs.h> |
5a0e3ad6a include cleanup: ... |
13 |
#include <linux/slab.h> |
dd2cc4dff mount options: fi... |
14 |
#include <linux/seq_file.h> |
6966a9775 UML: fix hostfs b... |
15 |
#include <linux/mount.h> |
d0352d3ed hostfs: sanitize ... |
16 |
#include <linux/namei.h> |
1da177e4c Linux-2.6.12-rc2 |
17 |
#include "hostfs.h" |
1da177e4c Linux-2.6.12-rc2 |
18 |
#include "init.h" |
84b3db04c uml: fix hostfs s... |
19 |
#include "kern.h" |
1da177e4c Linux-2.6.12-rc2 |
20 21 |
struct hostfs_inode_info { |
1da177e4c Linux-2.6.12-rc2 |
22 |
int fd; |
aeb5d7270 [PATCH] introduce... |
23 |
fmode_t mode; |
1da177e4c Linux-2.6.12-rc2 |
24 25 26 27 28 |
struct inode vfs_inode; }; static inline struct hostfs_inode_info *HOSTFS_I(struct inode *inode) { |
f1adc05e7 uml: hostfs style... |
29 |
return list_entry(inode, struct hostfs_inode_info, vfs_inode); |
1da177e4c Linux-2.6.12-rc2 |
30 |
} |
680b0da9b [PATCH] struct pa... |
31 |
#define FILE_HOSTFS_I(file) HOSTFS_I((file)->f_path.dentry->d_inode) |
1da177e4c Linux-2.6.12-rc2 |
32 |
|
fe15ce446 fs: change d_dele... |
33 |
static int hostfs_d_delete(const struct dentry *dentry) |
1da177e4c Linux-2.6.12-rc2 |
34 |
{ |
f1adc05e7 uml: hostfs style... |
35 |
return 1; |
1da177e4c Linux-2.6.12-rc2 |
36 |
} |
e16404ed0 constify dentry_o... |
37 |
static const struct dentry_operations hostfs_dentry_ops = { |
1da177e4c Linux-2.6.12-rc2 |
38 39 40 41 |
.d_delete = hostfs_d_delete, }; /* Changed in hostfs_args before the kernel starts running */ |
a6eb0be6d [PATCH] uml: host... |
42 |
static char *root_ino = ""; |
1da177e4c Linux-2.6.12-rc2 |
43 44 45 |
static int append = 0; #define HOSTFS_SUPER_MAGIC 0x00c0ffee |
92e1d5be9 [PATCH] mark stru... |
46 47 |
static const struct inode_operations hostfs_iops; static const struct inode_operations hostfs_dir_iops; |
d0352d3ed hostfs: sanitize ... |
48 |
static const struct inode_operations hostfs_link_iops; |
1da177e4c Linux-2.6.12-rc2 |
49 50 51 52 53 54 55 |
#ifndef MODULE static int __init hostfs_args(char *options, int *add) { char *ptr; ptr = strchr(options, ','); |
84b3db04c uml: fix hostfs s... |
56 |
if (ptr != NULL) |
1da177e4c Linux-2.6.12-rc2 |
57 |
*ptr++ = '\0'; |
84b3db04c uml: fix hostfs s... |
58 |
if (*options != '\0') |
1da177e4c Linux-2.6.12-rc2 |
59 60 61 |
root_ino = options; options = ptr; |
84b3db04c uml: fix hostfs s... |
62 |
while (options) { |
1da177e4c Linux-2.6.12-rc2 |
63 |
ptr = strchr(options, ','); |
84b3db04c uml: fix hostfs s... |
64 |
if (ptr != NULL) |
1da177e4c Linux-2.6.12-rc2 |
65 |
*ptr++ = '\0'; |
84b3db04c uml: fix hostfs s... |
66 67 |
if (*options != '\0') { if (!strcmp(options, "append")) |
1da177e4c Linux-2.6.12-rc2 |
68 69 70 71 72 73 74 |
append = 1; else printf("hostfs_args - unsupported option - %s ", options); } options = ptr; } |
f1adc05e7 uml: hostfs style... |
75 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
} __uml_setup("hostfs=", hostfs_args, "hostfs=<root dir>,<flags>,... " " This is used to set hostfs parameters. The root directory argument " " is used to confine all hostfs mounts to within the specified directory " " tree on the host. If this isn't specified, then a user inside UML can " " mount anything on the host that's accessible to the user that's running " " it. " " The only flag currently supported is 'append', which specifies that all " " files opened by hostfs will be opened in append mode. " ); #endif |
e9193059b hostfs: fix races... |
98 |
static char *__dentry_name(struct dentry *dentry, char *name) |
1da177e4c Linux-2.6.12-rc2 |
99 |
{ |
ec2447c27 hostfs: simplify ... |
100 |
char *p = dentry_path_raw(dentry, name, PATH_MAX); |
e9193059b hostfs: fix races... |
101 102 |
char *root; size_t len; |
1da177e4c Linux-2.6.12-rc2 |
103 |
|
e9193059b hostfs: fix races... |
104 105 106 107 |
root = dentry->d_sb->s_fs_info; len = strlen(root); if (IS_ERR(p)) { __putname(name); |
f1adc05e7 uml: hostfs style... |
108 |
return NULL; |
1da177e4c Linux-2.6.12-rc2 |
109 |
} |
850a496f9 hostfs: dumb (and... |
110 |
strlcpy(name, root, PATH_MAX); |
e9193059b hostfs: fix races... |
111 112 113 114 115 116 117 118 119 |
if (len > p - name) { __putname(name); return NULL; } if (p > name + len) { char *s = name + len; while ((*s++ = *p++) != '\0') ; } |
f1adc05e7 uml: hostfs style... |
120 |
return name; |
1da177e4c Linux-2.6.12-rc2 |
121 |
} |
e9193059b hostfs: fix races... |
122 123 124 125 126 |
static char *dentry_name(struct dentry *dentry) { char *name = __getname(); if (!name) return NULL; |
e9193059b hostfs: fix races... |
127 128 |
return __dentry_name(dentry, name); /* will unlock */ } |
c5322220e hostfs: get rid o... |
129 |
static char *inode_name(struct inode *ino) |
1da177e4c Linux-2.6.12-rc2 |
130 131 |
{ struct dentry *dentry; |
ec2447c27 hostfs: simplify ... |
132 |
char *name; |
1da177e4c Linux-2.6.12-rc2 |
133 |
|
ec2447c27 hostfs: simplify ... |
134 135 |
dentry = d_find_alias(ino); if (!dentry) |
e9193059b hostfs: fix races... |
136 |
return NULL; |
ec2447c27 hostfs: simplify ... |
137 138 139 140 141 142 |
name = dentry_name(dentry); dput(dentry); return name; |
1da177e4c Linux-2.6.12-rc2 |
143 |
} |
1da177e4c Linux-2.6.12-rc2 |
144 145 146 147 148 149 |
static char *follow_link(char *link) { int len, n; char *name, *resolved, *end; len = 64; |
84b3db04c uml: fix hostfs s... |
150 |
while (1) { |
1da177e4c Linux-2.6.12-rc2 |
151 152 |
n = -ENOMEM; name = kmalloc(len, GFP_KERNEL); |
84b3db04c uml: fix hostfs s... |
153 |
if (name == NULL) |
1da177e4c Linux-2.6.12-rc2 |
154 |
goto out; |
ea7e743e4 hostfs: fix a dup... |
155 |
n = hostfs_do_readlink(link, name, len); |
84b3db04c uml: fix hostfs s... |
156 |
if (n < len) |
1da177e4c Linux-2.6.12-rc2 |
157 158 159 160 |
break; len *= 2; kfree(name); } |
84b3db04c uml: fix hostfs s... |
161 |
if (n < 0) |
1da177e4c Linux-2.6.12-rc2 |
162 |
goto out_free; |
84b3db04c uml: fix hostfs s... |
163 |
if (*name == '/') |
f1adc05e7 uml: hostfs style... |
164 |
return name; |
1da177e4c Linux-2.6.12-rc2 |
165 166 |
end = strrchr(link, '/'); |
84b3db04c uml: fix hostfs s... |
167 |
if (end == NULL) |
f1adc05e7 uml: hostfs style... |
168 |
return name; |
1da177e4c Linux-2.6.12-rc2 |
169 170 171 172 173 |
*(end + 1) = '\0'; len = strlen(link) + strlen(name) + 1; resolved = kmalloc(len, GFP_KERNEL); |
84b3db04c uml: fix hostfs s... |
174 |
if (resolved == NULL) { |
1da177e4c Linux-2.6.12-rc2 |
175 176 177 178 179 180 181 |
n = -ENOMEM; goto out_free; } sprintf(resolved, "%s%s", link, name); kfree(name); kfree(link); |
f1adc05e7 uml: hostfs style... |
182 |
return resolved; |
1da177e4c Linux-2.6.12-rc2 |
183 184 185 186 |
out_free: kfree(name); out: |
f1adc05e7 uml: hostfs style... |
187 |
return ERR_PTR(n); |
1da177e4c Linux-2.6.12-rc2 |
188 |
} |
0a370e5de iget: stop HOSTFS... |
189 190 |
static struct inode *hostfs_iget(struct super_block *sb) { |
52b209f7b get rid of hostfs... |
191 |
struct inode *inode = new_inode(sb); |
0a370e5de iget: stop HOSTFS... |
192 193 |
if (!inode) return ERR_PTR(-ENOMEM); |
0a370e5de iget: stop HOSTFS... |
194 195 |
return inode; } |
726c33422 [PATCH] VFS: Perm... |
196 |
int hostfs_statfs(struct dentry *dentry, struct kstatfs *sf) |
1da177e4c Linux-2.6.12-rc2 |
197 |
{ |
84b3db04c uml: fix hostfs s... |
198 199 |
/* * do_statfs uses struct statfs64 internally, but the linux kernel |
1da177e4c Linux-2.6.12-rc2 |
200 201 202 203 204 205 206 207 208 |
* struct statfs still has 32-bit versions for most of these fields, * so we convert them here */ int err; long long f_blocks; long long f_bfree; long long f_bavail; long long f_files; long long f_ffree; |
601d2c38b hostfs: don't kee... |
209 |
err = do_statfs(dentry->d_sb->s_fs_info, |
1da177e4c Linux-2.6.12-rc2 |
210 211 |
&sf->f_bsize, &f_blocks, &f_bfree, &f_bavail, &f_files, &f_ffree, &sf->f_fsid, sizeof(sf->f_fsid), |
1b627d577 hostfs: fix UML c... |
212 |
&sf->f_namelen); |
84b3db04c uml: fix hostfs s... |
213 |
if (err) |
f1adc05e7 uml: hostfs style... |
214 |
return err; |
1da177e4c Linux-2.6.12-rc2 |
215 216 217 218 219 220 |
sf->f_blocks = f_blocks; sf->f_bfree = f_bfree; sf->f_bavail = f_bavail; sf->f_files = f_files; sf->f_ffree = f_ffree; sf->f_type = HOSTFS_SUPER_MAGIC; |
f1adc05e7 uml: hostfs style... |
221 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
222 223 224 225 226 |
} static struct inode *hostfs_alloc_inode(struct super_block *sb) { struct hostfs_inode_info *hi; |
601d2c38b hostfs: don't kee... |
227 |
hi = kzalloc(sizeof(*hi), GFP_KERNEL); |
84b3db04c uml: fix hostfs s... |
228 |
if (hi == NULL) |
f1adc05e7 uml: hostfs style... |
229 |
return NULL; |
601d2c38b hostfs: don't kee... |
230 |
hi->fd = -1; |
1da177e4c Linux-2.6.12-rc2 |
231 |
inode_init_once(&hi->vfs_inode); |
f1adc05e7 uml: hostfs style... |
232 |
return &hi->vfs_inode; |
1da177e4c Linux-2.6.12-rc2 |
233 |
} |
e971a6d7b stop icache pollu... |
234 |
static void hostfs_evict_inode(struct inode *inode) |
1da177e4c Linux-2.6.12-rc2 |
235 |
{ |
fef266580 [PATCH] update fi... |
236 |
truncate_inode_pages(&inode->i_data, 0); |
e971a6d7b stop icache pollu... |
237 |
end_writeback(inode); |
84b3db04c uml: fix hostfs s... |
238 |
if (HOSTFS_I(inode)->fd != -1) { |
1da177e4c Linux-2.6.12-rc2 |
239 240 241 |
close_file(&HOSTFS_I(inode)->fd); HOSTFS_I(inode)->fd = -1; } |
1da177e4c Linux-2.6.12-rc2 |
242 |
} |
fa0d7e3de fs: icache RCU fr... |
243 |
static void hostfs_i_callback(struct rcu_head *head) |
1da177e4c Linux-2.6.12-rc2 |
244 |
{ |
fa0d7e3de fs: icache RCU fr... |
245 |
struct inode *inode = container_of(head, struct inode, i_rcu); |
1da177e4c Linux-2.6.12-rc2 |
246 247 |
kfree(HOSTFS_I(inode)); } |
fa0d7e3de fs: icache RCU fr... |
248 249 250 251 252 |
static void hostfs_destroy_inode(struct inode *inode) { call_rcu(&inode->i_rcu, hostfs_i_callback); } |
1da177e4c Linux-2.6.12-rc2 |
253 |
|
34c80b1d9 vfs: switch ->sho... |
254 |
static int hostfs_show_options(struct seq_file *seq, struct dentry *root) |
dd2cc4dff mount options: fi... |
255 |
{ |
34c80b1d9 vfs: switch ->sho... |
256 |
const char *root_path = root->d_sb->s_fs_info; |
dd2cc4dff mount options: fi... |
257 258 259 260 261 262 263 |
size_t offset = strlen(root_ino) + 1; if (strlen(root_path) > offset) seq_printf(seq, ",%s", root_path + offset); return 0; } |
ee9b6d61a [PATCH] Mark stru... |
264 |
static const struct super_operations hostfs_sbops = { |
1da177e4c Linux-2.6.12-rc2 |
265 |
.alloc_inode = hostfs_alloc_inode, |
1da177e4c Linux-2.6.12-rc2 |
266 |
.destroy_inode = hostfs_destroy_inode, |
e971a6d7b stop icache pollu... |
267 |
.evict_inode = hostfs_evict_inode, |
1da177e4c Linux-2.6.12-rc2 |
268 |
.statfs = hostfs_statfs, |
dd2cc4dff mount options: fi... |
269 |
.show_options = hostfs_show_options, |
1da177e4c Linux-2.6.12-rc2 |
270 271 272 273 274 275 276 277 |
}; int hostfs_readdir(struct file *file, void *ent, filldir_t filldir) { void *dir; char *name; unsigned long long next, ino; int error, len; |
c5322220e hostfs: get rid o... |
278 |
name = dentry_name(file->f_path.dentry); |
84b3db04c uml: fix hostfs s... |
279 |
if (name == NULL) |
f1adc05e7 uml: hostfs style... |
280 |
return -ENOMEM; |
1da177e4c Linux-2.6.12-rc2 |
281 |
dir = open_dir(name, &error); |
e9193059b hostfs: fix races... |
282 |
__putname(name); |
84b3db04c uml: fix hostfs s... |
283 |
if (dir == NULL) |
f1adc05e7 uml: hostfs style... |
284 |
return -error; |
1da177e4c Linux-2.6.12-rc2 |
285 |
next = file->f_pos; |
84b3db04c uml: fix hostfs s... |
286 |
while ((name = read_dir(dir, &next, &ino, &len)) != NULL) { |
1da177e4c Linux-2.6.12-rc2 |
287 288 |
error = (*filldir)(ent, name, len, file->f_pos, ino, DT_UNKNOWN); |
84b3db04c uml: fix hostfs s... |
289 |
if (error) break; |
1da177e4c Linux-2.6.12-rc2 |
290 291 292 |
file->f_pos = next; } close_dir(dir); |
f1adc05e7 uml: hostfs style... |
293 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
294 295 296 297 |
} int hostfs_file_open(struct inode *ino, struct file *file) { |
f8ad850f1 try to get rid of... |
298 |
static DEFINE_MUTEX(open_mutex); |
1da177e4c Linux-2.6.12-rc2 |
299 |
char *name; |
aeb5d7270 [PATCH] introduce... |
300 |
fmode_t mode = 0; |
f8ad850f1 try to get rid of... |
301 |
int err; |
aeb5d7270 [PATCH] introduce... |
302 |
int r = 0, w = 0, fd; |
1da177e4c Linux-2.6.12-rc2 |
303 304 |
mode = file->f_mode & (FMODE_READ | FMODE_WRITE); |
84b3db04c uml: fix hostfs s... |
305 |
if ((mode & HOSTFS_I(ino)->mode) == mode) |
f1adc05e7 uml: hostfs style... |
306 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
307 |
|
f8ad850f1 try to get rid of... |
308 |
mode |= HOSTFS_I(ino)->mode; |
1da177e4c Linux-2.6.12-rc2 |
309 |
|
f8ad850f1 try to get rid of... |
310 311 |
retry: if (mode & FMODE_READ) |
1da177e4c Linux-2.6.12-rc2 |
312 |
r = 1; |
f8ad850f1 try to get rid of... |
313 |
if (mode & FMODE_WRITE) |
1da177e4c Linux-2.6.12-rc2 |
314 |
w = 1; |
84b3db04c uml: fix hostfs s... |
315 |
if (w) |
1da177e4c Linux-2.6.12-rc2 |
316 |
r = 1; |
c5322220e hostfs: get rid o... |
317 |
name = dentry_name(file->f_path.dentry); |
84b3db04c uml: fix hostfs s... |
318 |
if (name == NULL) |
f1adc05e7 uml: hostfs style... |
319 |
return -ENOMEM; |
1da177e4c Linux-2.6.12-rc2 |
320 321 |
fd = open_file(name, r, w, append); |
e9193059b hostfs: fix races... |
322 |
__putname(name); |
84b3db04c uml: fix hostfs s... |
323 |
if (fd < 0) |
f1adc05e7 uml: hostfs style... |
324 |
return fd; |
f8ad850f1 try to get rid of... |
325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 |
mutex_lock(&open_mutex); /* somebody else had handled it first? */ if ((mode & HOSTFS_I(ino)->mode) == mode) { mutex_unlock(&open_mutex); return 0; } if ((mode | HOSTFS_I(ino)->mode) != mode) { mode |= HOSTFS_I(ino)->mode; mutex_unlock(&open_mutex); close_file(&fd); goto retry; } if (HOSTFS_I(ino)->fd == -1) { HOSTFS_I(ino)->fd = fd; } else { err = replace_file(fd, HOSTFS_I(ino)->fd); close_file(&fd); if (err < 0) { mutex_unlock(&open_mutex); return err; } } HOSTFS_I(ino)->mode = mode; mutex_unlock(&open_mutex); |
1da177e4c Linux-2.6.12-rc2 |
350 |
|
f1adc05e7 uml: hostfs style... |
351 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
352 |
} |
02c24a821 fs: push i_mutex ... |
353 |
int hostfs_fsync(struct file *file, loff_t start, loff_t end, int datasync) |
1da177e4c Linux-2.6.12-rc2 |
354 |
{ |
02c24a821 fs: push i_mutex ... |
355 356 357 358 359 360 361 362 363 364 365 366 |
struct inode *inode = file->f_mapping->host; int ret; ret = filemap_write_and_wait_range(inode->i_mapping, start, end); if (ret) return ret; mutex_lock(&inode->i_mutex); ret = fsync_file(HOSTFS_I(inode)->fd, datasync); mutex_unlock(&inode->i_mutex); return ret; |
1da177e4c Linux-2.6.12-rc2 |
367 |
} |
4b6f5d20b [PATCH] Make most... |
368 |
static const struct file_operations hostfs_file_fops = { |
1da177e4c Linux-2.6.12-rc2 |
369 |
.llseek = generic_file_llseek, |
543ade1fc [PATCH] Streamlin... |
370 |
.read = do_sync_read, |
5ffc4ef45 sendfile: remove ... |
371 |
.splice_read = generic_file_splice_read, |
1da177e4c Linux-2.6.12-rc2 |
372 373 |
.aio_read = generic_file_aio_read, .aio_write = generic_file_aio_write, |
543ade1fc [PATCH] Streamlin... |
374 |
.write = do_sync_write, |
1da177e4c Linux-2.6.12-rc2 |
375 376 377 378 379 |
.mmap = generic_file_mmap, .open = hostfs_file_open, .release = NULL, .fsync = hostfs_fsync, }; |
4b6f5d20b [PATCH] Make most... |
380 |
static const struct file_operations hostfs_dir_fops = { |
1da177e4c Linux-2.6.12-rc2 |
381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 |
.llseek = generic_file_llseek, .readdir = hostfs_readdir, .read = generic_read_dir, }; int hostfs_writepage(struct page *page, struct writeback_control *wbc) { struct address_space *mapping = page->mapping; struct inode *inode = mapping->host; char *buffer; unsigned long long base; int count = PAGE_CACHE_SIZE; int end_index = inode->i_size >> PAGE_CACHE_SHIFT; int err; if (page->index >= end_index) count = inode->i_size & (PAGE_CACHE_SIZE-1); buffer = kmap(page); base = ((unsigned long long) page->index) << PAGE_CACHE_SHIFT; err = write_file(HOSTFS_I(inode)->fd, &base, buffer, count); |
84b3db04c uml: fix hostfs s... |
403 |
if (err != count) { |
1da177e4c Linux-2.6.12-rc2 |
404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 |
ClearPageUptodate(page); goto out; } if (base > inode->i_size) inode->i_size = base; if (PageError(page)) ClearPageError(page); err = 0; out: kunmap(page); unlock_page(page); return err; } int hostfs_readpage(struct file *file, struct page *page) { char *buffer; long long start; int err = 0; start = (long long) page->index << PAGE_CACHE_SHIFT; buffer = kmap(page); err = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer, PAGE_CACHE_SIZE); |
84b3db04c uml: fix hostfs s... |
432 433 |
if (err < 0) goto out; |
1da177e4c Linux-2.6.12-rc2 |
434 435 436 437 438 439 440 441 442 443 |
memset(&buffer[err], 0, PAGE_CACHE_SIZE - err); flush_dcache_page(page); SetPageUptodate(page); if (PageError(page)) ClearPageError(page); err = 0; out: kunmap(page); unlock_page(page); |
f1adc05e7 uml: hostfs style... |
444 |
return err; |
1da177e4c Linux-2.6.12-rc2 |
445 |
} |
ae361ff46 hostfs: convert t... |
446 447 448 |
int hostfs_write_begin(struct file *file, struct address_space *mapping, loff_t pos, unsigned len, unsigned flags, struct page **pagep, void **fsdata) |
1da177e4c Linux-2.6.12-rc2 |
449 |
{ |
ae361ff46 hostfs: convert t... |
450 |
pgoff_t index = pos >> PAGE_CACHE_SHIFT; |
1da177e4c Linux-2.6.12-rc2 |
451 |
|
54566b2c1 fs: symlink write... |
452 |
*pagep = grab_cache_page_write_begin(mapping, index, flags); |
ae361ff46 hostfs: convert t... |
453 454 455 |
if (!*pagep) return -ENOMEM; return 0; |
1da177e4c Linux-2.6.12-rc2 |
456 |
} |
ae361ff46 hostfs: convert t... |
457 458 459 |
int hostfs_write_end(struct file *file, struct address_space *mapping, loff_t pos, unsigned len, unsigned copied, struct page *page, void *fsdata) |
1da177e4c Linux-2.6.12-rc2 |
460 |
{ |
1da177e4c Linux-2.6.12-rc2 |
461 |
struct inode *inode = mapping->host; |
ae361ff46 hostfs: convert t... |
462 463 464 |
void *buffer; unsigned from = pos & (PAGE_CACHE_SIZE - 1); int err; |
1da177e4c Linux-2.6.12-rc2 |
465 |
|
1da177e4c Linux-2.6.12-rc2 |
466 |
buffer = kmap(page); |
ae361ff46 hostfs: convert t... |
467 468 |
err = write_file(FILE_HOSTFS_I(file)->fd, &pos, buffer + from, copied); kunmap(page); |
30f04a4ef [PATCH] uml: host... |
469 |
|
ae361ff46 hostfs: convert t... |
470 471 |
if (!PageUptodate(page) && err == PAGE_CACHE_SIZE) SetPageUptodate(page); |
30f04a4ef [PATCH] uml: host... |
472 |
|
84b3db04c uml: fix hostfs s... |
473 474 |
/* * If err > 0, write_file has added err to pos, so we are comparing |
ae361ff46 hostfs: convert t... |
475 476 477 478 479 480 |
* i_size against the last byte written. */ if (err > 0 && (pos > inode->i_size)) inode->i_size = pos; unlock_page(page); page_cache_release(page); |
1da177e4c Linux-2.6.12-rc2 |
481 |
|
f1adc05e7 uml: hostfs style... |
482 |
return err; |
1da177e4c Linux-2.6.12-rc2 |
483 |
} |
f5e54d6e5 [PATCH] mark addr... |
484 |
static const struct address_space_operations hostfs_aops = { |
1da177e4c Linux-2.6.12-rc2 |
485 486 |
.writepage = hostfs_writepage, .readpage = hostfs_readpage, |
ffa0aea68 [PATCH] uml - hos... |
487 |
.set_page_dirty = __set_page_dirty_nobuffers, |
ae361ff46 hostfs: convert t... |
488 489 |
.write_begin = hostfs_write_begin, .write_end = hostfs_write_end, |
1da177e4c Linux-2.6.12-rc2 |
490 |
}; |
4754b8255 hostfs: get rid o... |
491 |
static int read_name(struct inode *ino, char *name) |
1da177e4c Linux-2.6.12-rc2 |
492 |
{ |
4754b8255 hostfs: get rid o... |
493 494 495 496 497 |
dev_t rdev; struct hostfs_stat st; int err = stat_file(name, &st, -1); if (err) return err; |
1da177e4c Linux-2.6.12-rc2 |
498 |
|
5e2df28cc hostfs: pass path... |
499 |
/* Reencode maj and min with the kernel encoding.*/ |
4754b8255 hostfs: get rid o... |
500 |
rdev = MKDEV(st.maj, st.min); |
1da177e4c Linux-2.6.12-rc2 |
501 |
|
4754b8255 hostfs: get rid o... |
502 503 |
switch (st.mode & S_IFMT) { case S_IFLNK: |
d0352d3ed hostfs: sanitize ... |
504 |
ino->i_op = &hostfs_link_iops; |
1da177e4c Linux-2.6.12-rc2 |
505 |
break; |
4754b8255 hostfs: get rid o... |
506 507 508 |
case S_IFDIR: ino->i_op = &hostfs_dir_iops; ino->i_fop = &hostfs_dir_fops; |
1da177e4c Linux-2.6.12-rc2 |
509 |
break; |
4754b8255 hostfs: get rid o... |
510 511 512 513 514 515 |
case S_IFCHR: case S_IFBLK: case S_IFIFO: case S_IFSOCK: init_special_inode(ino, st.mode & S_IFMT, rdev); ino->i_op = &hostfs_iops; |
1da177e4c Linux-2.6.12-rc2 |
516 |
break; |
4754b8255 hostfs: get rid o... |
517 518 519 520 521 |
default: ino->i_op = &hostfs_iops; ino->i_fop = &hostfs_file_fops; ino->i_mapping->a_ops = &hostfs_aops; |
1da177e4c Linux-2.6.12-rc2 |
522 |
} |
4754b8255 hostfs: get rid o... |
523 524 525 |
ino->i_ino = st.ino; ino->i_mode = st.mode; |
bfe868486 filesystems: add ... |
526 |
set_nlink(ino, st.nlink); |
4754b8255 hostfs: get rid o... |
527 528 529 530 531 532 533 534 |
ino->i_uid = st.uid; ino->i_gid = st.gid; ino->i_atime = st.atime; ino->i_mtime = st.mtime; ino->i_ctime = st.ctime; ino->i_size = st.size; ino->i_blocks = st.blocks; return 0; |
1da177e4c Linux-2.6.12-rc2 |
535 |
} |
4acdaf27e switch ->create()... |
536 |
int hostfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, |
84b3db04c uml: fix hostfs s... |
537 |
struct nameidata *nd) |
1da177e4c Linux-2.6.12-rc2 |
538 539 540 541 |
{ struct inode *inode; char *name; int error, fd; |
0a370e5de iget: stop HOSTFS... |
542 543 544 |
inode = hostfs_iget(dir->i_sb); if (IS_ERR(inode)) { error = PTR_ERR(inode); |
84b3db04c uml: fix hostfs s... |
545 |
goto out; |
0a370e5de iget: stop HOSTFS... |
546 |
} |
1da177e4c Linux-2.6.12-rc2 |
547 |
|
1da177e4c Linux-2.6.12-rc2 |
548 |
error = -ENOMEM; |
c5322220e hostfs: get rid o... |
549 |
name = dentry_name(dentry); |
84b3db04c uml: fix hostfs s... |
550 |
if (name == NULL) |
1da177e4c Linux-2.6.12-rc2 |
551 552 553 554 555 556 |
goto out_put; 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); |
4754b8255 hostfs: get rid o... |
557 |
if (fd < 0) |
1da177e4c Linux-2.6.12-rc2 |
558 |
error = fd; |
4754b8255 hostfs: get rid o... |
559 |
else |
5e2df28cc hostfs: pass path... |
560 |
error = read_name(inode, name); |
1da177e4c Linux-2.6.12-rc2 |
561 |
|
e9193059b hostfs: fix races... |
562 |
__putname(name); |
84b3db04c uml: fix hostfs s... |
563 |
if (error) |
1da177e4c Linux-2.6.12-rc2 |
564 565 566 567 568 |
goto out_put; HOSTFS_I(inode)->fd = fd; HOSTFS_I(inode)->mode = FMODE_READ | FMODE_WRITE; d_instantiate(dentry, inode); |
f1adc05e7 uml: hostfs style... |
569 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
570 571 572 573 |
out_put: iput(inode); out: |
f1adc05e7 uml: hostfs style... |
574 |
return error; |
1da177e4c Linux-2.6.12-rc2 |
575 576 577 |
} struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry, |
f1adc05e7 uml: hostfs style... |
578 |
struct nameidata *nd) |
1da177e4c Linux-2.6.12-rc2 |
579 580 581 582 |
{ struct inode *inode; char *name; int err; |
0a370e5de iget: stop HOSTFS... |
583 584 585 |
inode = hostfs_iget(ino->i_sb); if (IS_ERR(inode)) { err = PTR_ERR(inode); |
1da177e4c Linux-2.6.12-rc2 |
586 |
goto out; |
0a370e5de iget: stop HOSTFS... |
587 |
} |
1da177e4c Linux-2.6.12-rc2 |
588 |
|
1da177e4c Linux-2.6.12-rc2 |
589 |
err = -ENOMEM; |
c5322220e hostfs: get rid o... |
590 |
name = dentry_name(dentry); |
84b3db04c uml: fix hostfs s... |
591 |
if (name == NULL) |
1da177e4c Linux-2.6.12-rc2 |
592 593 594 |
goto out_put; err = read_name(inode, name); |
5e2df28cc hostfs: pass path... |
595 |
|
e9193059b hostfs: fix races... |
596 |
__putname(name); |
84b3db04c uml: fix hostfs s... |
597 |
if (err == -ENOENT) { |
1da177e4c Linux-2.6.12-rc2 |
598 599 600 |
iput(inode); inode = NULL; } |
84b3db04c uml: fix hostfs s... |
601 |
else if (err) |
1da177e4c Linux-2.6.12-rc2 |
602 603 604 |
goto out_put; d_add(dentry, inode); |
f1adc05e7 uml: hostfs style... |
605 |
return NULL; |
1da177e4c Linux-2.6.12-rc2 |
606 607 608 609 |
out_put: iput(inode); out: |
f1adc05e7 uml: hostfs style... |
610 |
return ERR_PTR(err); |
1da177e4c Linux-2.6.12-rc2 |
611 |
} |
1da177e4c Linux-2.6.12-rc2 |
612 613 |
int hostfs_link(struct dentry *to, struct inode *ino, struct dentry *from) { |
f1adc05e7 uml: hostfs style... |
614 615 |
char *from_name, *to_name; int err; |
1da177e4c Linux-2.6.12-rc2 |
616 |
|
c5322220e hostfs: get rid o... |
617 |
if ((from_name = dentry_name(from)) == NULL) |
f1adc05e7 uml: hostfs style... |
618 |
return -ENOMEM; |
c5322220e hostfs: get rid o... |
619 |
to_name = dentry_name(to); |
84b3db04c uml: fix hostfs s... |
620 |
if (to_name == NULL) { |
e9193059b hostfs: fix races... |
621 |
__putname(from_name); |
f1adc05e7 uml: hostfs style... |
622 |
return -ENOMEM; |
1da177e4c Linux-2.6.12-rc2 |
623 |
} |
f1adc05e7 uml: hostfs style... |
624 |
err = link_file(to_name, from_name); |
e9193059b hostfs: fix races... |
625 626 |
__putname(from_name); __putname(to_name); |
f1adc05e7 uml: hostfs style... |
627 |
return err; |
1da177e4c Linux-2.6.12-rc2 |
628 629 630 631 632 633 |
} int hostfs_unlink(struct inode *ino, struct dentry *dentry) { char *file; int err; |
84b3db04c uml: fix hostfs s... |
634 |
if (append) |
f1adc05e7 uml: hostfs style... |
635 |
return -EPERM; |
1da177e4c Linux-2.6.12-rc2 |
636 |
|
f8d7e1877 leak in hostfs_un... |
637 638 |
if ((file = dentry_name(dentry)) == NULL) return -ENOMEM; |
1da177e4c Linux-2.6.12-rc2 |
639 |
err = unlink_file(file); |
e9193059b hostfs: fix races... |
640 |
__putname(file); |
f1adc05e7 uml: hostfs style... |
641 |
return err; |
1da177e4c Linux-2.6.12-rc2 |
642 643 644 645 646 647 |
} int hostfs_symlink(struct inode *ino, struct dentry *dentry, const char *to) { char *file; int err; |
c5322220e hostfs: get rid o... |
648 |
if ((file = dentry_name(dentry)) == NULL) |
f1adc05e7 uml: hostfs style... |
649 |
return -ENOMEM; |
1da177e4c Linux-2.6.12-rc2 |
650 |
err = make_symlink(file, to); |
e9193059b hostfs: fix races... |
651 |
__putname(file); |
f1adc05e7 uml: hostfs style... |
652 |
return err; |
1da177e4c Linux-2.6.12-rc2 |
653 |
} |
18bb1db3e switch vfs_mkdir(... |
654 |
int hostfs_mkdir(struct inode *ino, struct dentry *dentry, umode_t mode) |
1da177e4c Linux-2.6.12-rc2 |
655 656 657 |
{ char *file; int err; |
c5322220e hostfs: get rid o... |
658 |
if ((file = dentry_name(dentry)) == NULL) |
f1adc05e7 uml: hostfs style... |
659 |
return -ENOMEM; |
1da177e4c Linux-2.6.12-rc2 |
660 |
err = do_mkdir(file, mode); |
e9193059b hostfs: fix races... |
661 |
__putname(file); |
f1adc05e7 uml: hostfs style... |
662 |
return err; |
1da177e4c Linux-2.6.12-rc2 |
663 664 665 666 667 668 |
} int hostfs_rmdir(struct inode *ino, struct dentry *dentry) { char *file; int err; |
c5322220e hostfs: get rid o... |
669 |
if ((file = dentry_name(dentry)) == NULL) |
f1adc05e7 uml: hostfs style... |
670 |
return -ENOMEM; |
1da177e4c Linux-2.6.12-rc2 |
671 |
err = do_rmdir(file); |
e9193059b hostfs: fix races... |
672 |
__putname(file); |
f1adc05e7 uml: hostfs style... |
673 |
return err; |
1da177e4c Linux-2.6.12-rc2 |
674 |
} |
1a67aafb5 switch ->mknod() ... |
675 |
static int hostfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev) |
1da177e4c Linux-2.6.12-rc2 |
676 677 678 |
{ struct inode *inode; char *name; |
0a370e5de iget: stop HOSTFS... |
679 |
int err; |
1da177e4c Linux-2.6.12-rc2 |
680 |
|
0a370e5de iget: stop HOSTFS... |
681 682 683 |
inode = hostfs_iget(dir->i_sb); if (IS_ERR(inode)) { err = PTR_ERR(inode); |
1da177e4c Linux-2.6.12-rc2 |
684 |
goto out; |
0a370e5de iget: stop HOSTFS... |
685 |
} |
1da177e4c Linux-2.6.12-rc2 |
686 |
|
1da177e4c Linux-2.6.12-rc2 |
687 |
err = -ENOMEM; |
c5322220e hostfs: get rid o... |
688 |
name = dentry_name(dentry); |
84b3db04c uml: fix hostfs s... |
689 |
if (name == NULL) |
1da177e4c Linux-2.6.12-rc2 |
690 691 692 |
goto out_put; init_special_inode(inode, mode, dev); |
88f6cd0c3 [PATCH] uml: fix ... |
693 |
err = do_mknod(name, mode, MAJOR(dev), MINOR(dev)); |
e9193059b hostfs: fix races... |
694 |
if (!err) |
1da177e4c Linux-2.6.12-rc2 |
695 696 697 |
goto out_free; err = read_name(inode, name); |
e9193059b hostfs: fix races... |
698 |
__putname(name); |
5e2df28cc hostfs: pass path... |
699 700 |
if (err) goto out_put; |
84b3db04c uml: fix hostfs s... |
701 |
if (err) |
1da177e4c Linux-2.6.12-rc2 |
702 703 704 |
goto out_put; d_instantiate(dentry, inode); |
f1adc05e7 uml: hostfs style... |
705 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
706 707 |
out_free: |
e9193059b hostfs: fix races... |
708 |
__putname(name); |
1da177e4c Linux-2.6.12-rc2 |
709 710 711 |
out_put: iput(inode); out: |
f1adc05e7 uml: hostfs style... |
712 |
return err; |
1da177e4c Linux-2.6.12-rc2 |
713 714 715 716 717 718 719 |
} int hostfs_rename(struct inode *from_ino, struct dentry *from, struct inode *to_ino, struct dentry *to) { char *from_name, *to_name; int err; |
c5322220e hostfs: get rid o... |
720 |
if ((from_name = dentry_name(from)) == NULL) |
f1adc05e7 uml: hostfs style... |
721 |
return -ENOMEM; |
c5322220e hostfs: get rid o... |
722 |
if ((to_name = dentry_name(to)) == NULL) { |
e9193059b hostfs: fix races... |
723 |
__putname(from_name); |
f1adc05e7 uml: hostfs style... |
724 |
return -ENOMEM; |
1da177e4c Linux-2.6.12-rc2 |
725 726 |
} err = rename_file(from_name, to_name); |
e9193059b hostfs: fix races... |
727 728 |
__putname(from_name); __putname(to_name); |
f1adc05e7 uml: hostfs style... |
729 |
return err; |
1da177e4c Linux-2.6.12-rc2 |
730 |
} |
10556cb21 ->permission() sa... |
731 |
int hostfs_permission(struct inode *ino, int desired) |
1da177e4c Linux-2.6.12-rc2 |
732 733 734 |
{ char *name; int r = 0, w = 0, x = 0, err; |
10556cb21 ->permission() sa... |
735 |
if (desired & MAY_NOT_BLOCK) |
b74c79e99 fs: provide rcu-w... |
736 |
return -ECHILD; |
1da177e4c Linux-2.6.12-rc2 |
737 738 739 |
if (desired & MAY_READ) r = 1; if (desired & MAY_WRITE) w = 1; if (desired & MAY_EXEC) x = 1; |
c5322220e hostfs: get rid o... |
740 |
name = inode_name(ino); |
f1adc05e7 uml: hostfs style... |
741 742 |
if (name == NULL) return -ENOMEM; |
1da177e4c Linux-2.6.12-rc2 |
743 744 |
if (S_ISCHR(ino->i_mode) || S_ISBLK(ino->i_mode) || |
84b3db04c uml: fix hostfs s... |
745 |
S_ISFIFO(ino->i_mode) || S_ISSOCK(ino->i_mode)) |
1da177e4c Linux-2.6.12-rc2 |
746 747 748 |
err = 0; else err = access_file(name, r, w, x); |
e9193059b hostfs: fix races... |
749 |
__putname(name); |
84b3db04c uml: fix hostfs s... |
750 |
if (!err) |
2830ba7f3 ->permission() sa... |
751 |
err = generic_permission(ino, desired); |
1da177e4c Linux-2.6.12-rc2 |
752 753 754 755 756 |
return err; } int hostfs_setattr(struct dentry *dentry, struct iattr *attr) { |
1025774ce remove inode_setattr |
757 |
struct inode *inode = dentry->d_inode; |
1da177e4c Linux-2.6.12-rc2 |
758 759 760 |
struct hostfs_iattr attrs; char *name; int err; |
1025774ce remove inode_setattr |
761 |
int fd = HOSTFS_I(inode)->fd; |
5822b7fac uml: make hostfs_... |
762 |
|
1025774ce remove inode_setattr |
763 |
err = inode_change_ok(inode, attr); |
1da177e4c Linux-2.6.12-rc2 |
764 765 |
if (err) return err; |
84b3db04c uml: fix hostfs s... |
766 |
if (append) |
1da177e4c Linux-2.6.12-rc2 |
767 768 769 |
attr->ia_valid &= ~ATTR_SIZE; attrs.ia_valid = 0; |
84b3db04c uml: fix hostfs s... |
770 |
if (attr->ia_valid & ATTR_MODE) { |
1da177e4c Linux-2.6.12-rc2 |
771 772 773 |
attrs.ia_valid |= HOSTFS_ATTR_MODE; attrs.ia_mode = attr->ia_mode; } |
84b3db04c uml: fix hostfs s... |
774 |
if (attr->ia_valid & ATTR_UID) { |
1da177e4c Linux-2.6.12-rc2 |
775 776 777 |
attrs.ia_valid |= HOSTFS_ATTR_UID; attrs.ia_uid = attr->ia_uid; } |
84b3db04c uml: fix hostfs s... |
778 |
if (attr->ia_valid & ATTR_GID) { |
1da177e4c Linux-2.6.12-rc2 |
779 780 781 |
attrs.ia_valid |= HOSTFS_ATTR_GID; attrs.ia_gid = attr->ia_gid; } |
84b3db04c uml: fix hostfs s... |
782 |
if (attr->ia_valid & ATTR_SIZE) { |
1da177e4c Linux-2.6.12-rc2 |
783 784 785 |
attrs.ia_valid |= HOSTFS_ATTR_SIZE; attrs.ia_size = attr->ia_size; } |
84b3db04c uml: fix hostfs s... |
786 |
if (attr->ia_valid & ATTR_ATIME) { |
1da177e4c Linux-2.6.12-rc2 |
787 788 789 |
attrs.ia_valid |= HOSTFS_ATTR_ATIME; attrs.ia_atime = attr->ia_atime; } |
84b3db04c uml: fix hostfs s... |
790 |
if (attr->ia_valid & ATTR_MTIME) { |
1da177e4c Linux-2.6.12-rc2 |
791 792 793 |
attrs.ia_valid |= HOSTFS_ATTR_MTIME; attrs.ia_mtime = attr->ia_mtime; } |
84b3db04c uml: fix hostfs s... |
794 |
if (attr->ia_valid & ATTR_CTIME) { |
1da177e4c Linux-2.6.12-rc2 |
795 796 797 |
attrs.ia_valid |= HOSTFS_ATTR_CTIME; attrs.ia_ctime = attr->ia_ctime; } |
84b3db04c uml: fix hostfs s... |
798 |
if (attr->ia_valid & ATTR_ATIME_SET) { |
1da177e4c Linux-2.6.12-rc2 |
799 800 |
attrs.ia_valid |= HOSTFS_ATTR_ATIME_SET; } |
84b3db04c uml: fix hostfs s... |
801 |
if (attr->ia_valid & ATTR_MTIME_SET) { |
1da177e4c Linux-2.6.12-rc2 |
802 803 |
attrs.ia_valid |= HOSTFS_ATTR_MTIME_SET; } |
c5322220e hostfs: get rid o... |
804 |
name = dentry_name(dentry); |
84b3db04c uml: fix hostfs s... |
805 |
if (name == NULL) |
f1adc05e7 uml: hostfs style... |
806 |
return -ENOMEM; |
5822b7fac uml: make hostfs_... |
807 |
err = set_attr(name, &attrs, fd); |
e9193059b hostfs: fix races... |
808 |
__putname(name); |
84b3db04c uml: fix hostfs s... |
809 |
if (err) |
f1adc05e7 uml: hostfs style... |
810 |
return err; |
1da177e4c Linux-2.6.12-rc2 |
811 |
|
1025774ce remove inode_setattr |
812 813 814 815 816 817 818 819 820 821 822 823 |
if ((attr->ia_valid & ATTR_SIZE) && attr->ia_size != i_size_read(inode)) { int error; error = vmtruncate(inode, attr->ia_size); if (err) return err; } setattr_copy(inode, attr); mark_inode_dirty(inode); return 0; |
1da177e4c Linux-2.6.12-rc2 |
824 |
} |
92e1d5be9 [PATCH] mark stru... |
825 |
static const struct inode_operations hostfs_iops = { |
1da177e4c Linux-2.6.12-rc2 |
826 827 828 829 830 831 832 833 |
.create = hostfs_create, .link = hostfs_link, .unlink = hostfs_unlink, .symlink = hostfs_symlink, .mkdir = hostfs_mkdir, .rmdir = hostfs_rmdir, .mknod = hostfs_mknod, .rename = hostfs_rename, |
1da177e4c Linux-2.6.12-rc2 |
834 835 |
.permission = hostfs_permission, .setattr = hostfs_setattr, |
1da177e4c Linux-2.6.12-rc2 |
836 |
}; |
92e1d5be9 [PATCH] mark stru... |
837 |
static const struct inode_operations hostfs_dir_iops = { |
1da177e4c Linux-2.6.12-rc2 |
838 839 840 841 842 843 844 845 846 |
.create = hostfs_create, .lookup = hostfs_lookup, .link = hostfs_link, .unlink = hostfs_unlink, .symlink = hostfs_symlink, .mkdir = hostfs_mkdir, .rmdir = hostfs_rmdir, .mknod = hostfs_mknod, .rename = hostfs_rename, |
1da177e4c Linux-2.6.12-rc2 |
847 848 |
.permission = hostfs_permission, .setattr = hostfs_setattr, |
1da177e4c Linux-2.6.12-rc2 |
849 |
}; |
d0352d3ed hostfs: sanitize ... |
850 851 852 853 854 855 856 |
static void *hostfs_follow_link(struct dentry *dentry, struct nameidata *nd) { char *link = __getname(); if (link) { char *path = dentry_name(dentry); int err = -ENOMEM; if (path) { |
3b6036d14 hostfs ->follow_l... |
857 |
err = hostfs_do_readlink(path, link, PATH_MAX); |
d0352d3ed hostfs: sanitize ... |
858 859 |
if (err == PATH_MAX) err = -E2BIG; |
e9193059b hostfs: fix races... |
860 |
__putname(path); |
d0352d3ed hostfs: sanitize ... |
861 862 863 864 865 866 867 |
} if (err < 0) { __putname(link); link = ERR_PTR(err); } } else { link = ERR_PTR(-ENOMEM); |
1da177e4c Linux-2.6.12-rc2 |
868 |
} |
d0352d3ed hostfs: sanitize ... |
869 870 871 872 873 874 875 876 877 878 |
nd_set_link(nd, link); return NULL; } static void hostfs_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie) { char *s = nd_get_link(nd); if (!IS_ERR(s)) __putname(s); |
1da177e4c Linux-2.6.12-rc2 |
879 |
} |
d0352d3ed hostfs: sanitize ... |
880 881 882 883 |
static const struct inode_operations hostfs_link_iops = { .readlink = generic_readlink, .follow_link = hostfs_follow_link, .put_link = hostfs_put_link, |
1da177e4c Linux-2.6.12-rc2 |
884 885 886 887 888 |
}; static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent) { struct inode *root_inode; |
75e8defbe [PATCH] uml: host... |
889 |
char *host_root_path, *req_root = d; |
1da177e4c Linux-2.6.12-rc2 |
890 891 892 893 894 895 |
int err; sb->s_blocksize = 1024; sb->s_blocksize_bits = 10; sb->s_magic = HOSTFS_SUPER_MAGIC; sb->s_op = &hostfs_sbops; |
f772c4a6a switch hostfs |
896 |
sb->s_d_op = &hostfs_dentry_ops; |
752fa51e4 hostfs: set maxim... |
897 |
sb->s_maxbytes = MAX_LFS_FILESIZE; |
1da177e4c Linux-2.6.12-rc2 |
898 |
|
a6eb0be6d [PATCH] uml: host... |
899 |
/* NULL is printed as <NULL> by sprintf: avoid that. */ |
75e8defbe [PATCH] uml: host... |
900 901 |
if (req_root == NULL) req_root = ""; |
1da177e4c Linux-2.6.12-rc2 |
902 903 |
err = -ENOMEM; |
601d2c38b hostfs: don't kee... |
904 905 |
sb->s_fs_info = host_root_path = kmalloc(strlen(root_ino) + strlen(req_root) + 2, GFP_KERNEL); |
84b3db04c uml: fix hostfs s... |
906 |
if (host_root_path == NULL) |
1da177e4c Linux-2.6.12-rc2 |
907 |
goto out; |
75e8defbe [PATCH] uml: host... |
908 |
sprintf(host_root_path, "%s/%s", root_ino, req_root); |
1da177e4c Linux-2.6.12-rc2 |
909 |
|
52b209f7b get rid of hostfs... |
910 911 |
root_inode = new_inode(sb); if (!root_inode) |
601d2c38b hostfs: don't kee... |
912 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
913 |
|
4754b8255 hostfs: get rid o... |
914 915 916 |
err = read_name(root_inode, host_root_path); if (err) goto out_put; |
52b209f7b get rid of hostfs... |
917 |
|
4754b8255 hostfs: get rid o... |
918 |
if (S_ISLNK(root_inode->i_mode)) { |
52b209f7b get rid of hostfs... |
919 920 921 922 923 924 |
char *name = follow_link(host_root_path); if (IS_ERR(name)) err = PTR_ERR(name); else err = read_name(root_inode, name); kfree(name); |
4754b8255 hostfs: get rid o... |
925 926 |
if (err) goto out_put; |
52b209f7b get rid of hostfs... |
927 |
} |
1da177e4c Linux-2.6.12-rc2 |
928 |
|
1da177e4c Linux-2.6.12-rc2 |
929 930 |
err = -ENOMEM; sb->s_root = d_alloc_root(root_inode); |
84b3db04c uml: fix hostfs s... |
931 |
if (sb->s_root == NULL) |
1da177e4c Linux-2.6.12-rc2 |
932 |
goto out_put; |
f1adc05e7 uml: hostfs style... |
933 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
934 |
|
f1adc05e7 uml: hostfs style... |
935 936 |
out_put: iput(root_inode); |
f1adc05e7 uml: hostfs style... |
937 938 |
out: return err; |
1da177e4c Linux-2.6.12-rc2 |
939 |
} |
3c26ff6e4 convert get_sb_no... |
940 |
static struct dentry *hostfs_read_sb(struct file_system_type *type, |
454e2398b [PATCH] VFS: Perm... |
941 |
int flags, const char *dev_name, |
3c26ff6e4 convert get_sb_no... |
942 |
void *data) |
1da177e4c Linux-2.6.12-rc2 |
943 |
{ |
3c26ff6e4 convert get_sb_no... |
944 |
return mount_nodev(type, flags, data, hostfs_fill_sb_common); |
1da177e4c Linux-2.6.12-rc2 |
945 |
} |
601d2c38b hostfs: don't kee... |
946 947 948 949 950 |
static void hostfs_kill_sb(struct super_block *s) { kill_anon_super(s); kfree(s->s_fs_info); } |
1da177e4c Linux-2.6.12-rc2 |
951 952 953 |
static struct file_system_type hostfs_type = { .owner = THIS_MODULE, .name = "hostfs", |
3c26ff6e4 convert get_sb_no... |
954 |
.mount = hostfs_read_sb, |
601d2c38b hostfs: don't kee... |
955 |
.kill_sb = hostfs_kill_sb, |
1da177e4c Linux-2.6.12-rc2 |
956 957 958 959 960 |
.fs_flags = 0, }; static int __init init_hostfs(void) { |
f1adc05e7 uml: hostfs style... |
961 |
return register_filesystem(&hostfs_type); |
1da177e4c Linux-2.6.12-rc2 |
962 963 964 965 966 967 968 969 970 971 |
} static void __exit exit_hostfs(void) { unregister_filesystem(&hostfs_type); } module_init(init_hostfs) module_exit(exit_hostfs) MODULE_LICENSE("GPL"); |