drivers: power: report battery voltage in AOSP compatible format
[GitHub/mt8127/android_kernel_alcatel_ttab.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
280int hostfs_readdir(struct file *file, void *ent, filldir_t filldir)
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;
1da177e4 295 next = file->f_pos;
3ee6bd8e 296 while ((name = read_dir(dir, &next, &ino, &len, &type)) != NULL) {
1da177e4 297 error = (*filldir)(ent, name, len, file->f_pos,
3ee6bd8e 298 ino, type);
84b3db04 299 if (error) break;
1da177e4
LT
300 file->f_pos = next;
301 }
302 close_dir(dir);
f1adc05e 303 return 0;
1da177e4
LT
304}
305
306int hostfs_file_open(struct inode *ino, struct file *file)
307{
f8ad850f 308 static DEFINE_MUTEX(open_mutex);
1da177e4 309 char *name;
aeb5d727 310 fmode_t mode = 0;
f8ad850f 311 int err;
aeb5d727 312 int r = 0, w = 0, fd;
1da177e4
LT
313
314 mode = file->f_mode & (FMODE_READ | FMODE_WRITE);
84b3db04 315 if ((mode & HOSTFS_I(ino)->mode) == mode)
f1adc05e 316 return 0;
1da177e4 317
f8ad850f 318 mode |= HOSTFS_I(ino)->mode;
1da177e4 319
f8ad850f
AV
320retry:
321 if (mode & FMODE_READ)
1da177e4 322 r = 1;
f8ad850f 323 if (mode & FMODE_WRITE)
1da177e4 324 w = 1;
84b3db04 325 if (w)
1da177e4
LT
326 r = 1;
327
c5322220 328 name = dentry_name(file->f_path.dentry);
84b3db04 329 if (name == NULL)
f1adc05e 330 return -ENOMEM;
1da177e4
LT
331
332 fd = open_file(name, r, w, append);
e9193059 333 __putname(name);
84b3db04 334 if (fd < 0)
f1adc05e 335 return fd;
f8ad850f
AV
336
337 mutex_lock(&open_mutex);
338 /* somebody else had handled it first? */
339 if ((mode & HOSTFS_I(ino)->mode) == mode) {
340 mutex_unlock(&open_mutex);
341 return 0;
342 }
343 if ((mode | HOSTFS_I(ino)->mode) != mode) {
344 mode |= HOSTFS_I(ino)->mode;
345 mutex_unlock(&open_mutex);
346 close_file(&fd);
347 goto retry;
348 }
349 if (HOSTFS_I(ino)->fd == -1) {
350 HOSTFS_I(ino)->fd = fd;
351 } else {
352 err = replace_file(fd, HOSTFS_I(ino)->fd);
353 close_file(&fd);
354 if (err < 0) {
355 mutex_unlock(&open_mutex);
356 return err;
357 }
358 }
359 HOSTFS_I(ino)->mode = mode;
360 mutex_unlock(&open_mutex);
1da177e4 361
f1adc05e 362 return 0;
1da177e4
LT
363}
364
02c24a82 365int hostfs_fsync(struct file *file, loff_t start, loff_t end, int datasync)
1da177e4 366{
02c24a82
JB
367 struct inode *inode = file->f_mapping->host;
368 int ret;
369
370 ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
371 if (ret)
372 return ret;
373
374 mutex_lock(&inode->i_mutex);
375 ret = fsync_file(HOSTFS_I(inode)->fd, datasync);
376 mutex_unlock(&inode->i_mutex);
377
378 return ret;
1da177e4
LT
379}
380
4b6f5d20 381static const struct file_operations hostfs_file_fops = {
1da177e4 382 .llseek = generic_file_llseek,
543ade1f 383 .read = do_sync_read,
5ffc4ef4 384 .splice_read = generic_file_splice_read,
1da177e4
LT
385 .aio_read = generic_file_aio_read,
386 .aio_write = generic_file_aio_write,
543ade1f 387 .write = do_sync_write,
1da177e4
LT
388 .mmap = generic_file_mmap,
389 .open = hostfs_file_open,
390 .release = NULL,
391 .fsync = hostfs_fsync,
392};
393
4b6f5d20 394static const struct file_operations hostfs_dir_fops = {
1da177e4
LT
395 .llseek = generic_file_llseek,
396 .readdir = hostfs_readdir,
397 .read = generic_read_dir,
398};
399
400int hostfs_writepage(struct page *page, struct writeback_control *wbc)
401{
402 struct address_space *mapping = page->mapping;
403 struct inode *inode = mapping->host;
404 char *buffer;
405 unsigned long long base;
406 int count = PAGE_CACHE_SIZE;
407 int end_index = inode->i_size >> PAGE_CACHE_SHIFT;
408 int err;
409
410 if (page->index >= end_index)
411 count = inode->i_size & (PAGE_CACHE_SIZE-1);
412
413 buffer = kmap(page);
414 base = ((unsigned long long) page->index) << PAGE_CACHE_SHIFT;
415
416 err = write_file(HOSTFS_I(inode)->fd, &base, buffer, count);
84b3db04 417 if (err != count) {
1da177e4
LT
418 ClearPageUptodate(page);
419 goto out;
420 }
421
422 if (base > inode->i_size)
423 inode->i_size = base;
424
425 if (PageError(page))
426 ClearPageError(page);
427 err = 0;
428
429 out:
430 kunmap(page);
431
432 unlock_page(page);
433 return err;
434}
435
436int hostfs_readpage(struct file *file, struct page *page)
437{
438 char *buffer;
439 long long start;
440 int err = 0;
441
442 start = (long long) page->index << PAGE_CACHE_SHIFT;
443 buffer = kmap(page);
444 err = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer,
445 PAGE_CACHE_SIZE);
84b3db04
JD
446 if (err < 0)
447 goto out;
1da177e4
LT
448
449 memset(&buffer[err], 0, PAGE_CACHE_SIZE - err);
450
451 flush_dcache_page(page);
452 SetPageUptodate(page);
453 if (PageError(page)) ClearPageError(page);
454 err = 0;
455 out:
456 kunmap(page);
457 unlock_page(page);
f1adc05e 458 return err;
1da177e4
LT
459}
460
ae361ff4
NP
461int hostfs_write_begin(struct file *file, struct address_space *mapping,
462 loff_t pos, unsigned len, unsigned flags,
463 struct page **pagep, void **fsdata)
1da177e4 464{
ae361ff4 465 pgoff_t index = pos >> PAGE_CACHE_SHIFT;
1da177e4 466
54566b2c 467 *pagep = grab_cache_page_write_begin(mapping, index, flags);
ae361ff4
NP
468 if (!*pagep)
469 return -ENOMEM;
470 return 0;
1da177e4
LT
471}
472
ae361ff4
NP
473int hostfs_write_end(struct file *file, struct address_space *mapping,
474 loff_t pos, unsigned len, unsigned copied,
475 struct page *page, void *fsdata)
1da177e4 476{
1da177e4 477 struct inode *inode = mapping->host;
ae361ff4
NP
478 void *buffer;
479 unsigned from = pos & (PAGE_CACHE_SIZE - 1);
480 int err;
1da177e4 481
1da177e4 482 buffer = kmap(page);
ae361ff4
NP
483 err = write_file(FILE_HOSTFS_I(file)->fd, &pos, buffer + from, copied);
484 kunmap(page);
30f04a4e 485
ae361ff4
NP
486 if (!PageUptodate(page) && err == PAGE_CACHE_SIZE)
487 SetPageUptodate(page);
30f04a4e 488
84b3db04
JD
489 /*
490 * If err > 0, write_file has added err to pos, so we are comparing
ae361ff4
NP
491 * i_size against the last byte written.
492 */
493 if (err > 0 && (pos > inode->i_size))
494 inode->i_size = pos;
495 unlock_page(page);
496 page_cache_release(page);
1da177e4 497
f1adc05e 498 return err;
1da177e4
LT
499}
500
f5e54d6e 501static const struct address_space_operations hostfs_aops = {
1da177e4
LT
502 .writepage = hostfs_writepage,
503 .readpage = hostfs_readpage,
ffa0aea6 504 .set_page_dirty = __set_page_dirty_nobuffers,
ae361ff4
NP
505 .write_begin = hostfs_write_begin,
506 .write_end = hostfs_write_end,
1da177e4
LT
507};
508
4754b825 509static int read_name(struct inode *ino, char *name)
1da177e4 510{
4754b825
AV
511 dev_t rdev;
512 struct hostfs_stat st;
513 int err = stat_file(name, &st, -1);
514 if (err)
515 return err;
1da177e4 516
5e2df28c 517 /* Reencode maj and min with the kernel encoding.*/
4754b825 518 rdev = MKDEV(st.maj, st.min);
1da177e4 519
4754b825
AV
520 switch (st.mode & S_IFMT) {
521 case S_IFLNK:
d0352d3e 522 ino->i_op = &hostfs_link_iops;
1da177e4 523 break;
4754b825
AV
524 case S_IFDIR:
525 ino->i_op = &hostfs_dir_iops;
526 ino->i_fop = &hostfs_dir_fops;
1da177e4 527 break;
4754b825
AV
528 case S_IFCHR:
529 case S_IFBLK:
530 case S_IFIFO:
531 case S_IFSOCK:
532 init_special_inode(ino, st.mode & S_IFMT, rdev);
533 ino->i_op = &hostfs_iops;
1da177e4 534 break;
4754b825
AV
535
536 default:
537 ino->i_op = &hostfs_iops;
538 ino->i_fop = &hostfs_file_fops;
539 ino->i_mapping->a_ops = &hostfs_aops;
1da177e4 540 }
4754b825
AV
541
542 ino->i_ino = st.ino;
543 ino->i_mode = st.mode;
bfe86848 544 set_nlink(ino, st.nlink);
29f82ae5
EB
545 i_uid_write(ino, st.uid);
546 i_gid_write(ino, st.gid);
4754b825
AV
547 ino->i_atime = st.atime;
548 ino->i_mtime = st.mtime;
549 ino->i_ctime = st.ctime;
550 ino->i_size = st.size;
551 ino->i_blocks = st.blocks;
552 return 0;
1da177e4
LT
553}
554
4acdaf27 555int hostfs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
ebfc3b49 556 bool excl)
1da177e4
LT
557{
558 struct inode *inode;
559 char *name;
560 int error, fd;
561
0a370e5d
DH
562 inode = hostfs_iget(dir->i_sb);
563 if (IS_ERR(inode)) {
564 error = PTR_ERR(inode);
84b3db04 565 goto out;
0a370e5d 566 }
1da177e4 567
1da177e4 568 error = -ENOMEM;
c5322220 569 name = dentry_name(dentry);
84b3db04 570 if (name == NULL)
1da177e4
LT
571 goto out_put;
572
573 fd = file_create(name,
574 mode & S_IRUSR, mode & S_IWUSR, mode & S_IXUSR,
575 mode & S_IRGRP, mode & S_IWGRP, mode & S_IXGRP,
576 mode & S_IROTH, mode & S_IWOTH, mode & S_IXOTH);
4754b825 577 if (fd < 0)
1da177e4 578 error = fd;
4754b825 579 else
5e2df28c 580 error = read_name(inode, name);
1da177e4 581
e9193059 582 __putname(name);
84b3db04 583 if (error)
1da177e4
LT
584 goto out_put;
585
586 HOSTFS_I(inode)->fd = fd;
587 HOSTFS_I(inode)->mode = FMODE_READ | FMODE_WRITE;
588 d_instantiate(dentry, inode);
f1adc05e 589 return 0;
1da177e4
LT
590
591 out_put:
592 iput(inode);
593 out:
f1adc05e 594 return error;
1da177e4
LT
595}
596
597struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry,
00cd8dd3 598 unsigned int flags)
1da177e4
LT
599{
600 struct inode *inode;
601 char *name;
602 int err;
603
0a370e5d
DH
604 inode = hostfs_iget(ino->i_sb);
605 if (IS_ERR(inode)) {
606 err = PTR_ERR(inode);
1da177e4 607 goto out;
0a370e5d 608 }
1da177e4 609
1da177e4 610 err = -ENOMEM;
c5322220 611 name = dentry_name(dentry);
84b3db04 612 if (name == NULL)
1da177e4
LT
613 goto out_put;
614
615 err = read_name(inode, name);
5e2df28c 616
e9193059 617 __putname(name);
84b3db04 618 if (err == -ENOENT) {
1da177e4
LT
619 iput(inode);
620 inode = NULL;
621 }
84b3db04 622 else if (err)
1da177e4
LT
623 goto out_put;
624
625 d_add(dentry, inode);
f1adc05e 626 return NULL;
1da177e4
LT
627
628 out_put:
629 iput(inode);
630 out:
f1adc05e 631 return ERR_PTR(err);
1da177e4
LT
632}
633
1da177e4
LT
634int hostfs_link(struct dentry *to, struct inode *ino, struct dentry *from)
635{
f1adc05e
JD
636 char *from_name, *to_name;
637 int err;
1da177e4 638
c5322220 639 if ((from_name = dentry_name(from)) == NULL)
f1adc05e 640 return -ENOMEM;
c5322220 641 to_name = dentry_name(to);
84b3db04 642 if (to_name == NULL) {
e9193059 643 __putname(from_name);
f1adc05e 644 return -ENOMEM;
1da177e4 645 }
f1adc05e 646 err = link_file(to_name, from_name);
e9193059
AV
647 __putname(from_name);
648 __putname(to_name);
f1adc05e 649 return err;
1da177e4
LT
650}
651
652int hostfs_unlink(struct inode *ino, struct dentry *dentry)
653{
654 char *file;
655 int err;
656
84b3db04 657 if (append)
f1adc05e 658 return -EPERM;
1da177e4 659
f8d7e187
AV
660 if ((file = dentry_name(dentry)) == NULL)
661 return -ENOMEM;
662
1da177e4 663 err = unlink_file(file);
e9193059 664 __putname(file);
f1adc05e 665 return err;
1da177e4
LT
666}
667
668int hostfs_symlink(struct inode *ino, struct dentry *dentry, const char *to)
669{
670 char *file;
671 int err;
672
c5322220 673 if ((file = dentry_name(dentry)) == NULL)
f1adc05e 674 return -ENOMEM;
1da177e4 675 err = make_symlink(file, to);
e9193059 676 __putname(file);
f1adc05e 677 return err;
1da177e4
LT
678}
679
18bb1db3 680int hostfs_mkdir(struct inode *ino, struct dentry *dentry, umode_t mode)
1da177e4
LT
681{
682 char *file;
683 int err;
684
c5322220 685 if ((file = dentry_name(dentry)) == NULL)
f1adc05e 686 return -ENOMEM;
1da177e4 687 err = do_mkdir(file, mode);
e9193059 688 __putname(file);
f1adc05e 689 return err;
1da177e4
LT
690}
691
692int hostfs_rmdir(struct inode *ino, struct dentry *dentry)
693{
694 char *file;
695 int err;
696
c5322220 697 if ((file = dentry_name(dentry)) == NULL)
f1adc05e 698 return -ENOMEM;
1da177e4 699 err = do_rmdir(file);
e9193059 700 __putname(file);
f1adc05e 701 return err;
1da177e4
LT
702}
703
1a67aafb 704static int hostfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev)
1da177e4
LT
705{
706 struct inode *inode;
707 char *name;
0a370e5d 708 int err;
1da177e4 709
0a370e5d
DH
710 inode = hostfs_iget(dir->i_sb);
711 if (IS_ERR(inode)) {
712 err = PTR_ERR(inode);
1da177e4 713 goto out;
0a370e5d 714 }
1da177e4 715
1da177e4 716 err = -ENOMEM;
c5322220 717 name = dentry_name(dentry);
84b3db04 718 if (name == NULL)
1da177e4
LT
719 goto out_put;
720
721 init_special_inode(inode, mode, dev);
88f6cd0c 722 err = do_mknod(name, mode, MAJOR(dev), MINOR(dev));
4c77a512 723 if (err)
1da177e4
LT
724 goto out_free;
725
726 err = read_name(inode, name);
e9193059 727 __putname(name);
5e2df28c
AV
728 if (err)
729 goto out_put;
1da177e4
LT
730
731 d_instantiate(dentry, inode);
f1adc05e 732 return 0;
1da177e4
LT
733
734 out_free:
e9193059 735 __putname(name);
1da177e4
LT
736 out_put:
737 iput(inode);
738 out:
f1adc05e 739 return err;
1da177e4
LT
740}
741
742int hostfs_rename(struct inode *from_ino, struct dentry *from,
743 struct inode *to_ino, struct dentry *to)
744{
745 char *from_name, *to_name;
746 int err;
747
c5322220 748 if ((from_name = dentry_name(from)) == NULL)
f1adc05e 749 return -ENOMEM;
c5322220 750 if ((to_name = dentry_name(to)) == NULL) {
e9193059 751 __putname(from_name);
f1adc05e 752 return -ENOMEM;
1da177e4
LT
753 }
754 err = rename_file(from_name, to_name);
e9193059
AV
755 __putname(from_name);
756 __putname(to_name);
f1adc05e 757 return err;
1da177e4
LT
758}
759
10556cb2 760int hostfs_permission(struct inode *ino, int desired)
1da177e4
LT
761{
762 char *name;
763 int r = 0, w = 0, x = 0, err;
764
10556cb2 765 if (desired & MAY_NOT_BLOCK)
b74c79e9
NP
766 return -ECHILD;
767
1da177e4
LT
768 if (desired & MAY_READ) r = 1;
769 if (desired & MAY_WRITE) w = 1;
770 if (desired & MAY_EXEC) x = 1;
c5322220 771 name = inode_name(ino);
f1adc05e
JD
772 if (name == NULL)
773 return -ENOMEM;
1da177e4
LT
774
775 if (S_ISCHR(ino->i_mode) || S_ISBLK(ino->i_mode) ||
84b3db04 776 S_ISFIFO(ino->i_mode) || S_ISSOCK(ino->i_mode))
1da177e4
LT
777 err = 0;
778 else
779 err = access_file(name, r, w, x);
e9193059 780 __putname(name);
84b3db04 781 if (!err)
2830ba7f 782 err = generic_permission(ino, desired);
1da177e4
LT
783 return err;
784}
785
786int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
787{
1025774c 788 struct inode *inode = dentry->d_inode;
1da177e4
LT
789 struct hostfs_iattr attrs;
790 char *name;
791 int err;
792
1025774c 793 int fd = HOSTFS_I(inode)->fd;
5822b7fa 794
1025774c 795 err = inode_change_ok(inode, attr);
1da177e4
LT
796 if (err)
797 return err;
798
84b3db04 799 if (append)
1da177e4
LT
800 attr->ia_valid &= ~ATTR_SIZE;
801
802 attrs.ia_valid = 0;
84b3db04 803 if (attr->ia_valid & ATTR_MODE) {
1da177e4
LT
804 attrs.ia_valid |= HOSTFS_ATTR_MODE;
805 attrs.ia_mode = attr->ia_mode;
806 }
84b3db04 807 if (attr->ia_valid & ATTR_UID) {
1da177e4 808 attrs.ia_valid |= HOSTFS_ATTR_UID;
29f82ae5 809 attrs.ia_uid = from_kuid(&init_user_ns, attr->ia_uid);
1da177e4 810 }
84b3db04 811 if (attr->ia_valid & ATTR_GID) {
1da177e4 812 attrs.ia_valid |= HOSTFS_ATTR_GID;
29f82ae5 813 attrs.ia_gid = from_kgid(&init_user_ns, attr->ia_gid);
1da177e4 814 }
84b3db04 815 if (attr->ia_valid & ATTR_SIZE) {
1da177e4
LT
816 attrs.ia_valid |= HOSTFS_ATTR_SIZE;
817 attrs.ia_size = attr->ia_size;
818 }
84b3db04 819 if (attr->ia_valid & ATTR_ATIME) {
1da177e4
LT
820 attrs.ia_valid |= HOSTFS_ATTR_ATIME;
821 attrs.ia_atime = attr->ia_atime;
822 }
84b3db04 823 if (attr->ia_valid & ATTR_MTIME) {
1da177e4
LT
824 attrs.ia_valid |= HOSTFS_ATTR_MTIME;
825 attrs.ia_mtime = attr->ia_mtime;
826 }
84b3db04 827 if (attr->ia_valid & ATTR_CTIME) {
1da177e4
LT
828 attrs.ia_valid |= HOSTFS_ATTR_CTIME;
829 attrs.ia_ctime = attr->ia_ctime;
830 }
84b3db04 831 if (attr->ia_valid & ATTR_ATIME_SET) {
1da177e4
LT
832 attrs.ia_valid |= HOSTFS_ATTR_ATIME_SET;
833 }
84b3db04 834 if (attr->ia_valid & ATTR_MTIME_SET) {
1da177e4
LT
835 attrs.ia_valid |= HOSTFS_ATTR_MTIME_SET;
836 }
c5322220 837 name = dentry_name(dentry);
84b3db04 838 if (name == NULL)
f1adc05e 839 return -ENOMEM;
5822b7fa 840 err = set_attr(name, &attrs, fd);
e9193059 841 __putname(name);
84b3db04 842 if (err)
f1adc05e 843 return err;
1da177e4 844
1025774c 845 if ((attr->ia_valid & ATTR_SIZE) &&
bc077320 846 attr->ia_size != i_size_read(inode))
3be2be0a 847 truncate_setsize(inode, attr->ia_size);
1025774c
CH
848
849 setattr_copy(inode, attr);
850 mark_inode_dirty(inode);
851 return 0;
1da177e4
LT
852}
853
92e1d5be 854static const struct inode_operations hostfs_iops = {
1da177e4
LT
855 .permission = hostfs_permission,
856 .setattr = hostfs_setattr,
1da177e4
LT
857};
858
92e1d5be 859static const struct inode_operations hostfs_dir_iops = {
1da177e4
LT
860 .create = hostfs_create,
861 .lookup = hostfs_lookup,
862 .link = hostfs_link,
863 .unlink = hostfs_unlink,
864 .symlink = hostfs_symlink,
865 .mkdir = hostfs_mkdir,
866 .rmdir = hostfs_rmdir,
867 .mknod = hostfs_mknod,
868 .rename = hostfs_rename,
1da177e4
LT
869 .permission = hostfs_permission,
870 .setattr = hostfs_setattr,
1da177e4
LT
871};
872
d0352d3e
AV
873static void *hostfs_follow_link(struct dentry *dentry, struct nameidata *nd)
874{
875 char *link = __getname();
876 if (link) {
877 char *path = dentry_name(dentry);
878 int err = -ENOMEM;
879 if (path) {
3b6036d1 880 err = hostfs_do_readlink(path, link, PATH_MAX);
d0352d3e
AV
881 if (err == PATH_MAX)
882 err = -E2BIG;
e9193059 883 __putname(path);
d0352d3e
AV
884 }
885 if (err < 0) {
886 __putname(link);
887 link = ERR_PTR(err);
888 }
889 } else {
890 link = ERR_PTR(-ENOMEM);
1da177e4 891 }
d0352d3e
AV
892
893 nd_set_link(nd, link);
894 return NULL;
895}
896
897static void hostfs_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
898{
899 char *s = nd_get_link(nd);
900 if (!IS_ERR(s))
901 __putname(s);
1da177e4
LT
902}
903
d0352d3e
AV
904static const struct inode_operations hostfs_link_iops = {
905 .readlink = generic_readlink,
906 .follow_link = hostfs_follow_link,
907 .put_link = hostfs_put_link,
1da177e4
LT
908};
909
910static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent)
911{
912 struct inode *root_inode;
75e8defb 913 char *host_root_path, *req_root = d;
1da177e4
LT
914 int err;
915
916 sb->s_blocksize = 1024;
917 sb->s_blocksize_bits = 10;
918 sb->s_magic = HOSTFS_SUPER_MAGIC;
919 sb->s_op = &hostfs_sbops;
f772c4a6 920 sb->s_d_op = &hostfs_dentry_ops;
752fa51e 921 sb->s_maxbytes = MAX_LFS_FILESIZE;
1da177e4 922
a6eb0be6 923 /* NULL is printed as <NULL> by sprintf: avoid that. */
75e8defb
PBG
924 if (req_root == NULL)
925 req_root = "";
1da177e4
LT
926
927 err = -ENOMEM;
601d2c38
AV
928 sb->s_fs_info = host_root_path =
929 kmalloc(strlen(root_ino) + strlen(req_root) + 2, GFP_KERNEL);
84b3db04 930 if (host_root_path == NULL)
1da177e4
LT
931 goto out;
932
75e8defb 933 sprintf(host_root_path, "%s/%s", root_ino, req_root);
1da177e4 934
52b209f7
AV
935 root_inode = new_inode(sb);
936 if (!root_inode)
601d2c38 937 goto out;
1da177e4 938
4754b825
AV
939 err = read_name(root_inode, host_root_path);
940 if (err)
941 goto out_put;
52b209f7 942
4754b825 943 if (S_ISLNK(root_inode->i_mode)) {
52b209f7 944 char *name = follow_link(host_root_path);
cb1f02fd 945 if (IS_ERR(name)) {
52b209f7 946 err = PTR_ERR(name);
cb1f02fd
DC
947 goto out_put;
948 }
949 err = read_name(root_inode, name);
52b209f7 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");