You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs pile 1 from Al Viro: "This is _not_ all; in particular, Miklos' and Jan's stuff is not there yet." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (64 commits) ext4: initialization of ext4_li_mtx needs to be done earlier debugfs-related mode_t whack-a-mole hfsplus: add an ioctl to bless files hfsplus: change finder_info to u32 hfsplus: initialise userflags qnx4: new helper - try_extent() qnx4: get rid of qnx4_bread/qnx4_getblk take removal of PF_FORKNOEXEC to flush_old_exec() trim includes in inode.c um: uml_dup_mmap() relies on ->mmap_sem being held, but activate_mm() doesn't hold it um: embed ->stub_pages[] into mmu_context gadgetfs: list_for_each_safe() misuse ocfs2: fix leaks on failure exits in module_init ecryptfs: make register_filesystem() the last potential failure exit ntfs: forgets to unregister sysctls on register_filesystem() failure logfs: missing cleanup on register_filesystem() failure jfs: mising cleanup on register_filesystem() failure make configfs_pin_fs() return root dentry on success configfs: configfs_create_dir() has parent dentry in dentry->d_parent configfs: sanitize configfs_create() ...
This commit is contained in:
@@ -136,7 +136,7 @@ file.
|
||||
void __iomem *base;
|
||||
};
|
||||
|
||||
struct dentry *debugfs_create_regset32(const char *name, mode_t mode,
|
||||
struct dentry *debugfs_create_regset32(const char *name, umode_t mode,
|
||||
struct dentry *parent,
|
||||
struct debugfs_regset32 *regset);
|
||||
|
||||
|
||||
@@ -429,3 +429,9 @@ filemap_write_and_wait_range() so that all dirty pages are synced out properly.
|
||||
You must also keep in mind that ->fsync() is not called with i_mutex held
|
||||
anymore, so if you require i_mutex locking you must make sure to take it and
|
||||
release it yourself.
|
||||
|
||||
--
|
||||
[mandatory]
|
||||
d_alloc_root() is gone, along with a lot of bugs caused by code
|
||||
misusing it. Replacement: d_make_root(inode). The difference is,
|
||||
d_make_root() drops the reference to inode if dentry allocation fails.
|
||||
|
||||
@@ -0,0 +1,174 @@
|
||||
The QNX6 Filesystem
|
||||
===================
|
||||
|
||||
The qnx6fs is used by newer QNX operating system versions. (e.g. Neutrino)
|
||||
It got introduced in QNX 6.4.0 and is used default since 6.4.1.
|
||||
|
||||
Option
|
||||
======
|
||||
|
||||
mmi_fs Mount filesystem as used for example by Audi MMI 3G system
|
||||
|
||||
Specification
|
||||
=============
|
||||
|
||||
qnx6fs shares many properties with traditional Unix filesystems. It has the
|
||||
concepts of blocks, inodes and directories.
|
||||
On QNX it is possible to create little endian and big endian qnx6 filesystems.
|
||||
This feature makes it possible to create and use a different endianness fs
|
||||
for the target (QNX is used on quite a range of embedded systems) plattform
|
||||
running on a different endianess.
|
||||
The Linux driver handles endianness transparently. (LE and BE)
|
||||
|
||||
Blocks
|
||||
------
|
||||
|
||||
The space in the device or file is split up into blocks. These are a fixed
|
||||
size of 512, 1024, 2048 or 4096, which is decided when the filesystem is
|
||||
created.
|
||||
Blockpointers are 32bit, so the maximum space that can be adressed is
|
||||
2^32 * 4096 bytes or 16TB
|
||||
|
||||
The superblocks
|
||||
---------------
|
||||
|
||||
The superblock contains all global information about the filesystem.
|
||||
Each qnx6fs got two superblocks, each one having a 64bit serial number.
|
||||
That serial number is used to identify the "active" superblock.
|
||||
In write mode with reach new snapshot (after each synchronous write), the
|
||||
serial of the new master superblock is increased (old superblock serial + 1)
|
||||
|
||||
So basically the snapshot functionality is realized by an atomic final
|
||||
update of the serial number. Before updating that serial, all modifications
|
||||
are done by copying all modified blocks during that specific write request
|
||||
(or period) and building up a new (stable) filesystem structure under the
|
||||
inactive superblock.
|
||||
|
||||
Each superblock holds a set of root inodes for the different filesystem
|
||||
parts. (Inode, Bitmap and Longfilenames)
|
||||
Each of these root nodes holds information like total size of the stored
|
||||
data and the adressing levels in that specific tree.
|
||||
If the level value is 0, up to 16 direct blocks can be adressed by each
|
||||
node.
|
||||
Level 1 adds an additional indirect adressing level where each indirect
|
||||
adressing block holds up to blocksize / 4 bytes pointers to data blocks.
|
||||
Level 2 adds an additional indirect adressig block level (so, already up
|
||||
to 16 * 256 * 256 = 1048576 blocks that can be adressed by such a tree)a
|
||||
|
||||
Unused block pointers are always set to ~0 - regardless of root node,
|
||||
indirect adressing blocks or inodes.
|
||||
Data leaves are always on the lowest level. So no data is stored on upper
|
||||
tree levels.
|
||||
|
||||
The first Superblock is located at 0x2000. (0x2000 is the bootblock size)
|
||||
The Audi MMI 3G first superblock directly starts at byte 0.
|
||||
Second superblock position can either be calculated from the superblock
|
||||
information (total number of filesystem blocks) or by taking the highest
|
||||
device address, zeroing the last 3 bytes and then substracting 0x1000 from
|
||||
that address.
|
||||
|
||||
0x1000 is the size reserved for each superblock - regardless of the
|
||||
blocksize of the filesystem.
|
||||
|
||||
Inodes
|
||||
------
|
||||
|
||||
Each object in the filesystem is represented by an inode. (index node)
|
||||
The inode structure contains pointers to the filesystem blocks which contain
|
||||
the data held in the object and all of the metadata about an object except
|
||||
its longname. (filenames longer than 27 characters)
|
||||
The metadata about an object includes the permissions, owner, group, flags,
|
||||
size, number of blocks used, access time, change time and modification time.
|
||||
|
||||
Object mode field is POSIX format. (which makes things easier)
|
||||
|
||||
There are also pointers to the first 16 blocks, if the object data can be
|
||||
adressed with 16 direct blocks.
|
||||
For more than 16 blocks an indirect adressing in form of another tree is
|
||||
used. (scheme is the same as the one used for the superblock root nodes)
|
||||
|
||||
The filesize is stored 64bit. Inode counting starts with 1. (whilst long
|
||||
filename inodes start with 0)
|
||||
|
||||
Directories
|
||||
-----------
|
||||
|
||||
A directory is a filesystem object and has an inode just like a file.
|
||||
It is a specially formatted file containing records which associate each
|
||||
name with an inode number.
|
||||
'.' inode number points to the directory inode
|
||||
'..' inode number points to the parent directory inode
|
||||
Eeach filename record additionally got a filename length field.
|
||||
|
||||
One special case are long filenames or subdirectory names.
|
||||
These got set a filename length field of 0xff in the corresponding directory
|
||||
record plus the longfile inode number also stored in that record.
|
||||
With that longfilename inode number, the longfilename tree can be walked
|
||||
starting with the superblock longfilename root node pointers.
|
||||
|
||||
Special files
|
||||
-------------
|
||||
|
||||
Symbolic links are also filesystem objects with inodes. They got a specific
|
||||
bit in the inode mode field identifying them as symbolic link.
|
||||
The directory entry file inode pointer points to the target file inode.
|
||||
|
||||
Hard links got an inode, a directory entry, but a specific mode bit set,
|
||||
no block pointers and the directory file record pointing to the target file
|
||||
inode.
|
||||
|
||||
Character and block special devices do not exist in QNX as those files
|
||||
are handled by the QNX kernel/drivers and created in /dev independant of the
|
||||
underlaying filesystem.
|
||||
|
||||
Long filenames
|
||||
--------------
|
||||
|
||||
Long filenames are stored in a seperate adressing tree. The staring point
|
||||
is the longfilename root node in the active superblock.
|
||||
Each data block (tree leaves) holds one long filename. That filename is
|
||||
limited to 510 bytes. The first two starting bytes are used as length field
|
||||
for the actual filename.
|
||||
If that structure shall fit for all allowed blocksizes, it is clear why there
|
||||
is a limit of 510 bytes for the actual filename stored.
|
||||
|
||||
Bitmap
|
||||
------
|
||||
|
||||
The qnx6fs filesystem allocation bitmap is stored in a tree under bitmap
|
||||
root node in the superblock and each bit in the bitmap represents one
|
||||
filesystem block.
|
||||
The first block is block 0, which starts 0x1000 after superblock start.
|
||||
So for a normal qnx6fs 0x3000 (bootblock + superblock) is the physical
|
||||
address at which block 0 is located.
|
||||
|
||||
Bits at the end of the last bitmap block are set to 1, if the device is
|
||||
smaller than addressing space in the bitmap.
|
||||
|
||||
Bitmap system area
|
||||
------------------
|
||||
|
||||
The bitmap itself is devided into three parts.
|
||||
First the system area, that is split into two halfs.
|
||||
Then userspace.
|
||||
|
||||
The requirement for a static, fixed preallocated system area comes from how
|
||||
qnx6fs deals with writes.
|
||||
Each superblock got it's own half of the system area. So superblock #1
|
||||
always uses blocks from the lower half whilst superblock #2 just writes to
|
||||
blocks represented by the upper half bitmap system area bits.
|
||||
|
||||
Bitmap blocks, Inode blocks and indirect addressing blocks for those two
|
||||
tree structures are treated as system blocks.
|
||||
|
||||
The rational behind that is that a write request can work on a new snapshot
|
||||
(system area of the inactive - resp. lower serial numbered superblock) while
|
||||
at the same time there is still a complete stable filesystem structer in the
|
||||
other half of the system area.
|
||||
|
||||
When finished with writing (a sync write is completed, the maximum sync leap
|
||||
time or a filesystem sync is requested), serial of the previously inactive
|
||||
superblock atomically is increased and the fs switches over to that - then
|
||||
stable declared - superblock.
|
||||
|
||||
For all data outside the system area, blocks are just copied while writing.
|
||||
@@ -218,6 +218,7 @@ Code Seq#(hex) Include File Comments
|
||||
'h' 00-7F conflict! Charon filesystem
|
||||
<mailto:zapman@interlan.net>
|
||||
'h' 00-1F linux/hpet.h conflict!
|
||||
'h' 80-8F fs/hfsplus/ioctl.c
|
||||
'i' 00-3F linux/i2o-dev.h conflict!
|
||||
'i' 0B-1F linux/ipmi.h conflict!
|
||||
'i' 80-8F linux/i8k.h
|
||||
|
||||
@@ -46,6 +46,7 @@ static struct linux_binfmt loader_format = {
|
||||
|
||||
static int __init init_loader_binfmt(void)
|
||||
{
|
||||
return insert_binfmt(&loader_format);
|
||||
insert_binfmt(&loader_format);
|
||||
return 0;
|
||||
}
|
||||
arch_initcall(init_loader_binfmt);
|
||||
|
||||
@@ -757,9 +757,9 @@ spufs_create_root(struct super_block *sb, void *data)
|
||||
goto out_iput;
|
||||
|
||||
ret = -ENOMEM;
|
||||
sb->s_root = d_alloc_root(inode);
|
||||
sb->s_root = d_make_root(inode);
|
||||
if (!sb->s_root)
|
||||
goto out_iput;
|
||||
goto out;
|
||||
|
||||
return 0;
|
||||
out_iput:
|
||||
@@ -828,19 +828,19 @@ static int __init spufs_init(void)
|
||||
ret = spu_sched_init();
|
||||
if (ret)
|
||||
goto out_cache;
|
||||
ret = register_filesystem(&spufs_type);
|
||||
if (ret)
|
||||
goto out_sched;
|
||||
ret = register_spu_syscalls(&spufs_calls);
|
||||
if (ret)
|
||||
goto out_fs;
|
||||
goto out_sched;
|
||||
ret = register_filesystem(&spufs_type);
|
||||
if (ret)
|
||||
goto out_syscalls;
|
||||
|
||||
spufs_init_isolated_loader();
|
||||
|
||||
return 0;
|
||||
|
||||
out_fs:
|
||||
unregister_filesystem(&spufs_type);
|
||||
out_syscalls:
|
||||
unregister_spu_syscalls(&spufs_calls);
|
||||
out_sched:
|
||||
spu_sched_exit();
|
||||
out_cache:
|
||||
|
||||
@@ -293,11 +293,9 @@ static int hypfs_fill_super(struct super_block *sb, void *data, int silent)
|
||||
return -ENOMEM;
|
||||
root_inode->i_op = &simple_dir_inode_operations;
|
||||
root_inode->i_fop = &simple_dir_operations;
|
||||
sb->s_root = root_dentry = d_alloc_root(root_inode);
|
||||
if (!root_dentry) {
|
||||
iput(root_inode);
|
||||
sb->s_root = root_dentry = d_make_root(root_inode);
|
||||
if (!root_dentry)
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (MACHINE_IS_VM)
|
||||
rc = hypfs_vm_create_files(sb, root_dentry);
|
||||
else
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
typedef struct mm_context {
|
||||
struct mm_id id;
|
||||
struct uml_arch_mm_context arch;
|
||||
struct page **stub_pages;
|
||||
struct page *stub_pages[2];
|
||||
} mm_context_t;
|
||||
|
||||
extern void __switch_mm(struct mm_id * mm_idp);
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <linux/sched.h>
|
||||
#include <asm/mmu.h>
|
||||
|
||||
extern void arch_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm);
|
||||
extern void uml_setup_stubs(struct mm_struct *mm);
|
||||
extern void arch_exit_mmap(struct mm_struct *mm);
|
||||
|
||||
#define deactivate_mm(tsk,mm) do { } while (0)
|
||||
@@ -23,7 +23,9 @@ static inline void activate_mm(struct mm_struct *old, struct mm_struct *new)
|
||||
* when the new ->mm is used for the first time.
|
||||
*/
|
||||
__switch_mm(&new->context.id);
|
||||
arch_dup_mmap(old, new);
|
||||
down_write(&new->mmap_sem);
|
||||
uml_setup_stubs(new);
|
||||
up_write(&new->mmap_sem);
|
||||
}
|
||||
|
||||
static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
|
||||
@@ -39,6 +41,11 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
|
||||
}
|
||||
}
|
||||
|
||||
static inline void arch_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm)
|
||||
{
|
||||
uml_setup_stubs(mm);
|
||||
}
|
||||
|
||||
static inline void enter_lazy_tlb(struct mm_struct *mm,
|
||||
struct task_struct *tsk)
|
||||
{
|
||||
|
||||
@@ -92,8 +92,6 @@ int init_new_context(struct task_struct *task, struct mm_struct *mm)
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
to_mm->stub_pages = NULL;
|
||||
|
||||
return 0;
|
||||
|
||||
out_free:
|
||||
@@ -103,7 +101,7 @@ int init_new_context(struct task_struct *task, struct mm_struct *mm)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void arch_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm)
|
||||
void uml_setup_stubs(struct mm_struct *mm)
|
||||
{
|
||||
struct page **pages;
|
||||
int err, ret;
|
||||
@@ -120,29 +118,20 @@ void arch_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm)
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
pages = kmalloc(2 * sizeof(struct page *), GFP_KERNEL);
|
||||
if (pages == NULL) {
|
||||
printk(KERN_ERR "arch_dup_mmap failed to allocate 2 page "
|
||||
"pointers\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
pages[0] = virt_to_page(&__syscall_stub_start);
|
||||
pages[1] = virt_to_page(mm->context.id.stack);
|
||||
mm->context.stub_pages = pages;
|
||||
mm->context.stub_pages[0] = virt_to_page(&__syscall_stub_start);
|
||||
mm->context.stub_pages[1] = virt_to_page(mm->context.id.stack);
|
||||
|
||||
/* dup_mmap already holds mmap_sem */
|
||||
err = install_special_mapping(mm, STUB_START, STUB_END - STUB_START,
|
||||
VM_READ | VM_MAYREAD | VM_EXEC |
|
||||
VM_MAYEXEC | VM_DONTCOPY, pages);
|
||||
VM_MAYEXEC | VM_DONTCOPY,
|
||||
mm->context.stub_pages);
|
||||
if (err) {
|
||||
printk(KERN_ERR "install_special_mapping returned %d\n", err);
|
||||
goto out_free;
|
||||
goto out;
|
||||
}
|
||||
return;
|
||||
|
||||
out_free:
|
||||
kfree(pages);
|
||||
out:
|
||||
force_sigsegv(SIGSEGV, current);
|
||||
}
|
||||
@@ -151,8 +140,6 @@ void arch_exit_mmap(struct mm_struct *mm)
|
||||
{
|
||||
pte_t *pte;
|
||||
|
||||
if (mm->context.stub_pages != NULL)
|
||||
kfree(mm->context.stub_pages);
|
||||
pte = virt_to_pte(mm, STUB_CODE);
|
||||
if (pte != NULL)
|
||||
pte_clear(mm, STUB_CODE, pte);
|
||||
|
||||
@@ -323,7 +323,6 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs)
|
||||
}
|
||||
|
||||
install_exec_creds(bprm);
|
||||
current->flags &= ~PF_FORKNOEXEC;
|
||||
|
||||
if (N_MAGIC(ex) == OMAGIC) {
|
||||
unsigned long text_addr, map_size;
|
||||
@@ -519,7 +518,8 @@ out:
|
||||
|
||||
static int __init init_aout_binfmt(void)
|
||||
{
|
||||
return register_binfmt(&aout_format);
|
||||
register_binfmt(&aout_format);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit exit_aout_binfmt(void)
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
static LIST_HEAD(service_processors);
|
||||
|
||||
static struct inode *ibmasmfs_make_inode(struct super_block *sb, int mode);
|
||||
static void ibmasmfs_create_files (struct super_block *sb, struct dentry *root);
|
||||
static void ibmasmfs_create_files (struct super_block *sb);
|
||||
static int ibmasmfs_fill_super (struct super_block *sb, void *data, int silent);
|
||||
|
||||
|
||||
@@ -114,7 +114,6 @@ static struct file_system_type ibmasmfs_type = {
|
||||
static int ibmasmfs_fill_super (struct super_block *sb, void *data, int silent)
|
||||
{
|
||||
struct inode *root;
|
||||
struct dentry *root_dentry;
|
||||
|
||||
sb->s_blocksize = PAGE_CACHE_SIZE;
|
||||
sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
|
||||
@@ -129,14 +128,11 @@ static int ibmasmfs_fill_super (struct super_block *sb, void *data, int silent)
|
||||
root->i_op = &simple_dir_inode_operations;
|
||||
root->i_fop = ibmasmfs_dir_ops;
|
||||
|
||||
root_dentry = d_alloc_root(root);
|
||||
if (!root_dentry) {
|
||||
iput(root);
|
||||
sb->s_root = d_make_root(root);
|
||||
if (!sb->s_root)
|
||||
return -ENOMEM;
|
||||
}
|
||||
sb->s_root = root_dentry;
|
||||
|
||||
ibmasmfs_create_files(sb, root_dentry);
|
||||
ibmasmfs_create_files(sb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -612,7 +608,7 @@ static const struct file_operations remote_settings_fops = {
|
||||
};
|
||||
|
||||
|
||||
static void ibmasmfs_create_files (struct super_block *sb, struct dentry *root)
|
||||
static void ibmasmfs_create_files (struct super_block *sb)
|
||||
{
|
||||
struct list_head *entry;
|
||||
struct service_processor *sp;
|
||||
@@ -621,7 +617,7 @@ static void ibmasmfs_create_files (struct super_block *sb, struct dentry *root)
|
||||
struct dentry *dir;
|
||||
struct dentry *remote_dir;
|
||||
sp = list_entry(entry, struct service_processor, node);
|
||||
dir = ibmasmfs_create_dir(sb, root, sp->dirname);
|
||||
dir = ibmasmfs_create_dir(sb, sb->s_root, sp->dirname);
|
||||
if (!dir)
|
||||
continue;
|
||||
|
||||
|
||||
@@ -211,18 +211,17 @@ static void __exit ibmasm_exit (void)
|
||||
|
||||
static int __init ibmasm_init(void)
|
||||
{
|
||||
int result;
|
||||
int result = pci_register_driver(&ibmasm_driver);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
result = ibmasmfs_register();
|
||||
if (result) {
|
||||
pci_unregister_driver(&ibmasm_driver);
|
||||
err("Failed to register ibmasmfs file system");
|
||||
return result;
|
||||
}
|
||||
result = pci_register_driver(&ibmasm_driver);
|
||||
if (result) {
|
||||
ibmasmfs_unregister();
|
||||
return result;
|
||||
}
|
||||
|
||||
ibmasm_register_panic_notifier();
|
||||
info(DRIVER_DESC " version " DRIVER_VERSION " loaded");
|
||||
return 0;
|
||||
|
||||
@@ -1685,7 +1685,7 @@ static int mmc_add_disk(struct mmc_blk_data *md)
|
||||
|
||||
if ((md->area_type & MMC_BLK_DATA_AREA_BOOT) &&
|
||||
card->ext_csd.boot_ro_lockable) {
|
||||
mode_t mode;
|
||||
umode_t mode;
|
||||
|
||||
if (card->ext_csd.boot_ro_lock & EXT_CSD_BOOT_WP_B_PWR_WP_DIS)
|
||||
mode = S_IRUGO;
|
||||
|
||||
@@ -516,7 +516,7 @@ static const struct file_operations bnad_debugfs_op_drvinfo = {
|
||||
|
||||
struct bnad_debugfs_entry {
|
||||
const char *name;
|
||||
mode_t mode;
|
||||
umode_t mode;
|
||||
const struct file_operations *fops;
|
||||
};
|
||||
|
||||
|
||||
@@ -238,7 +238,6 @@ struct dentry *oprofilefs_mkdir(struct super_block *sb,
|
||||
static int oprofilefs_fill_super(struct super_block *sb, void *data, int silent)
|
||||
{
|
||||
struct inode *root_inode;
|
||||
struct dentry *root_dentry;
|
||||
|
||||
sb->s_blocksize = PAGE_CACHE_SIZE;
|
||||
sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
|
||||
@@ -251,15 +250,11 @@ static int oprofilefs_fill_super(struct super_block *sb, void *data, int silent)
|
||||
return -ENOMEM;
|
||||
root_inode->i_op = &simple_dir_inode_operations;
|
||||
root_inode->i_fop = &simple_dir_operations;
|
||||
root_dentry = d_alloc_root(root_inode);
|
||||
if (!root_dentry) {
|
||||
iput(root_inode);
|
||||
sb->s_root = d_make_root(root_inode);
|
||||
if (!sb->s_root)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
sb->s_root = root_dentry;
|
||||
|
||||
oprofile_create_files(sb, root_dentry);
|
||||
oprofile_create_files(sb, sb->s_root);
|
||||
|
||||
// FIXME: verify kill_litter_super removes our dentries
|
||||
return 0;
|
||||
|
||||
@@ -50,7 +50,6 @@
|
||||
static const struct file_operations default_file_operations;
|
||||
static struct vfsmount *usbfs_mount;
|
||||
static int usbfs_mount_count; /* = 0 */
|
||||
static int ignore_mount = 0;
|
||||
|
||||
static struct dentry *devices_usbfs_dentry;
|
||||
static int num_buses; /* = 0 */
|
||||
@@ -256,7 +255,7 @@ static int remount(struct super_block *sb, int *flags, char *data)
|
||||
* i.e. it's a simple_pin_fs from create_special_files,
|
||||
* then ignore it.
|
||||
*/
|
||||
if (ignore_mount)
|
||||
if (*flags & MS_KERNMOUNT)
|
||||
return 0;
|
||||
|
||||
if (parse_options(sb, data)) {
|
||||
@@ -454,7 +453,6 @@ static const struct super_operations usbfs_ops = {
|
||||
static int usbfs_fill_super(struct super_block *sb, void *data, int silent)
|
||||
{
|
||||
struct inode *inode;
|
||||
struct dentry *root;
|
||||
|
||||
sb->s_blocksize = PAGE_CACHE_SIZE;
|
||||
sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
|
||||
@@ -462,19 +460,11 @@ static int usbfs_fill_super(struct super_block *sb, void *data, int silent)
|
||||
sb->s_op = &usbfs_ops;
|
||||
sb->s_time_gran = 1;
|
||||
inode = usbfs_get_inode(sb, S_IFDIR | 0755, 0);
|
||||
|
||||
if (!inode) {
|
||||
dbg("%s: could not get inode!",__func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
root = d_alloc_root(inode);
|
||||
if (!root) {
|
||||
sb->s_root = d_make_root(inode);
|
||||
if (!sb->s_root) {
|
||||
dbg("%s: could not get root dentry!",__func__);
|
||||
iput(inode);
|
||||
return -ENOMEM;
|
||||
}
|
||||
sb->s_root = root;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -591,11 +581,6 @@ static int create_special_files (void)
|
||||
struct dentry *parent;
|
||||
int retval;
|
||||
|
||||
/* the simple_pin_fs calls will call remount with no options
|
||||
* without this flag that would overwrite the real mount options (if any)
|
||||
*/
|
||||
ignore_mount = 1;
|
||||
|
||||
/* create the devices special file */
|
||||
retval = simple_pin_fs(&usb_fs_type, &usbfs_mount, &usbfs_mount_count);
|
||||
if (retval) {
|
||||
@@ -603,8 +588,6 @@ static int create_special_files (void)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ignore_mount = 0;
|
||||
|
||||
parent = usbfs_mount->mnt_root;
|
||||
devices_usbfs_dentry = fs_create_file ("devices",
|
||||
listmode | S_IFREG, parent,
|
||||
|
||||
@@ -1063,13 +1063,9 @@ static int ffs_sb_fill(struct super_block *sb, void *_data, int silent)
|
||||
&simple_dir_operations,
|
||||
&simple_dir_inode_operations,
|
||||
&data->perms);
|
||||
if (unlikely(!inode))
|
||||
sb->s_root = d_make_root(inode);
|
||||
if (unlikely(!sb->s_root))
|
||||
goto Enomem;
|
||||
sb->s_root = d_alloc_root(inode);
|
||||
if (unlikely(!sb->s_root)) {
|
||||
iput(inode);
|
||||
goto Enomem;
|
||||
}
|
||||
|
||||
/* EP0 file */
|
||||
if (unlikely(!ffs_sb_create_file(sb, "ep0", ffs,
|
||||
|
||||
@@ -1571,20 +1571,18 @@ delegate:
|
||||
|
||||
static void destroy_ep_files (struct dev_data *dev)
|
||||
{
|
||||
struct list_head *entry, *tmp;
|
||||
|
||||
DBG (dev, "%s %d\n", __func__, dev->state);
|
||||
|
||||
/* dev->state must prevent interference */
|
||||
restart:
|
||||
spin_lock_irq (&dev->lock);
|
||||
list_for_each_safe (entry, tmp, &dev->epfiles) {
|
||||
while (!list_empty(&dev->epfiles)) {
|
||||
struct ep_data *ep;
|
||||
struct inode *parent;
|
||||
struct dentry *dentry;
|
||||
|
||||
/* break link to FS */
|
||||
ep = list_entry (entry, struct ep_data, epfiles);
|
||||
ep = list_first_entry (&dev->epfiles, struct ep_data, epfiles);
|
||||
list_del_init (&ep->epfiles);
|
||||
dentry = ep->dentry;
|
||||
ep->dentry = NULL;
|
||||
@@ -1607,8 +1605,7 @@ restart:
|
||||
dput (dentry);
|
||||
mutex_unlock (&parent->i_mutex);
|
||||
|
||||
/* fds may still be open */
|
||||
goto restart;
|
||||
spin_lock_irq (&dev->lock);
|
||||
}
|
||||
spin_unlock_irq (&dev->lock);
|
||||
}
|
||||
@@ -2061,10 +2058,8 @@ gadgetfs_fill_super (struct super_block *sb, void *opts, int silent)
|
||||
if (!inode)
|
||||
goto Enomem;
|
||||
inode->i_op = &simple_dir_inode_operations;
|
||||
if (!(sb->s_root = d_alloc_root (inode))) {
|
||||
iput(inode);
|
||||
if (!(sb->s_root = d_make_root (inode)))
|
||||
goto Enomem;
|
||||
}
|
||||
|
||||
/* the ep0 file is named after the controller we expect;
|
||||
* user mode code can use it for sanity checks, like we do.
|
||||
|
||||
+8
-8
@@ -594,21 +594,21 @@ static int __init init_v9fs(void)
|
||||
int err;
|
||||
pr_info("Installing v9fs 9p2000 file system support\n");
|
||||
/* TODO: Setup list of registered trasnport modules */
|
||||
err = register_filesystem(&v9fs_fs_type);
|
||||
if (err < 0) {
|
||||
pr_err("Failed to register filesystem\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
err = v9fs_cache_register();
|
||||
if (err < 0) {
|
||||
pr_err("Failed to register v9fs for caching\n");
|
||||
goto out_fs_unreg;
|
||||
return err;
|
||||
}
|
||||
|
||||
err = v9fs_sysfs_init();
|
||||
if (err < 0) {
|
||||
pr_err("Failed to register with sysfs\n");
|
||||
goto out_cache;
|
||||
}
|
||||
err = register_filesystem(&v9fs_fs_type);
|
||||
if (err < 0) {
|
||||
pr_err("Failed to register filesystem\n");
|
||||
goto out_sysfs_cleanup;
|
||||
}
|
||||
|
||||
@@ -617,8 +617,8 @@ static int __init init_v9fs(void)
|
||||
out_sysfs_cleanup:
|
||||
v9fs_sysfs_cleanup();
|
||||
|
||||
out_fs_unreg:
|
||||
unregister_filesystem(&v9fs_fs_type);
|
||||
out_cache:
|
||||
v9fs_cache_unregister();
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user