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