dect
/
linux-2.6
Archived
13
0
Fork 0

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:
Linus Torvalds 2012-03-21 13:36:41 -07:00
commit e2a0883e40
186 changed files with 5363 additions and 4144 deletions

View File

@ -136,7 +136,7 @@ file.
void __iomem *base; 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 dentry *parent,
struct debugfs_regset32 *regset); struct debugfs_regset32 *regset);

View File

@ -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 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 anymore, so if you require i_mutex locking you must make sure to take it and
release it yourself. 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.

View File

@ -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.

View File

@ -218,6 +218,7 @@ Code Seq#(hex) Include File Comments
'h' 00-7F conflict! Charon filesystem 'h' 00-7F conflict! Charon filesystem
<mailto:zapman@interlan.net> <mailto:zapman@interlan.net>
'h' 00-1F linux/hpet.h conflict! 'h' 00-1F linux/hpet.h conflict!
'h' 80-8F fs/hfsplus/ioctl.c
'i' 00-3F linux/i2o-dev.h conflict! 'i' 00-3F linux/i2o-dev.h conflict!
'i' 0B-1F linux/ipmi.h conflict! 'i' 0B-1F linux/ipmi.h conflict!
'i' 80-8F linux/i8k.h 'i' 80-8F linux/i8k.h

View File

@ -46,6 +46,7 @@ static struct linux_binfmt loader_format = {
static int __init init_loader_binfmt(void) static int __init init_loader_binfmt(void)
{ {
return insert_binfmt(&loader_format); insert_binfmt(&loader_format);
return 0;
} }
arch_initcall(init_loader_binfmt); arch_initcall(init_loader_binfmt);

View File

@ -757,9 +757,9 @@ spufs_create_root(struct super_block *sb, void *data)
goto out_iput; goto out_iput;
ret = -ENOMEM; ret = -ENOMEM;
sb->s_root = d_alloc_root(inode); sb->s_root = d_make_root(inode);
if (!sb->s_root) if (!sb->s_root)
goto out_iput; goto out;
return 0; return 0;
out_iput: out_iput:
@ -828,19 +828,19 @@ static int __init spufs_init(void)
ret = spu_sched_init(); ret = spu_sched_init();
if (ret) if (ret)
goto out_cache; goto out_cache;
ret = register_filesystem(&spufs_type);
if (ret)
goto out_sched;
ret = register_spu_syscalls(&spufs_calls); ret = register_spu_syscalls(&spufs_calls);
if (ret) if (ret)
goto out_fs; goto out_sched;
ret = register_filesystem(&spufs_type);
if (ret)
goto out_syscalls;
spufs_init_isolated_loader(); spufs_init_isolated_loader();
return 0; return 0;
out_fs: out_syscalls:
unregister_filesystem(&spufs_type); unregister_spu_syscalls(&spufs_calls);
out_sched: out_sched:
spu_sched_exit(); spu_sched_exit();
out_cache: out_cache:

View File

@ -293,11 +293,9 @@ static int hypfs_fill_super(struct super_block *sb, void *data, int silent)
return -ENOMEM; return -ENOMEM;
root_inode->i_op = &simple_dir_inode_operations; root_inode->i_op = &simple_dir_inode_operations;
root_inode->i_fop = &simple_dir_operations; root_inode->i_fop = &simple_dir_operations;
sb->s_root = root_dentry = d_alloc_root(root_inode); sb->s_root = root_dentry = d_make_root(root_inode);
if (!root_dentry) { if (!root_dentry)
iput(root_inode);
return -ENOMEM; return -ENOMEM;
}
if (MACHINE_IS_VM) if (MACHINE_IS_VM)
rc = hypfs_vm_create_files(sb, root_dentry); rc = hypfs_vm_create_files(sb, root_dentry);
else else

View File

@ -12,7 +12,7 @@
typedef struct mm_context { typedef struct mm_context {
struct mm_id id; struct mm_id id;
struct uml_arch_mm_context arch; struct uml_arch_mm_context arch;
struct page **stub_pages; struct page *stub_pages[2];
} mm_context_t; } mm_context_t;
extern void __switch_mm(struct mm_id * mm_idp); extern void __switch_mm(struct mm_id * mm_idp);

View File

@ -9,7 +9,7 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <asm/mmu.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); extern void arch_exit_mmap(struct mm_struct *mm);
#define deactivate_mm(tsk,mm) do { } while (0) #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. * when the new ->mm is used for the first time.
*/ */
__switch_mm(&new->context.id); __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, 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, static inline void enter_lazy_tlb(struct mm_struct *mm,
struct task_struct *tsk) struct task_struct *tsk)
{ {

View File

@ -92,8 +92,6 @@ int init_new_context(struct task_struct *task, struct mm_struct *mm)
goto out_free; goto out_free;
} }
to_mm->stub_pages = NULL;
return 0; return 0;
out_free: out_free:
@ -103,7 +101,7 @@ int init_new_context(struct task_struct *task, struct mm_struct *mm)
return ret; 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; struct page **pages;
int err, ret; int err, ret;
@ -120,29 +118,20 @@ void arch_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm)
if (ret) if (ret)
goto out; goto out;
pages = kmalloc(2 * sizeof(struct page *), GFP_KERNEL); mm->context.stub_pages[0] = virt_to_page(&__syscall_stub_start);
if (pages == NULL) { mm->context.stub_pages[1] = virt_to_page(mm->context.id.stack);
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;
/* dup_mmap already holds mmap_sem */ /* dup_mmap already holds mmap_sem */
err = install_special_mapping(mm, STUB_START, STUB_END - STUB_START, err = install_special_mapping(mm, STUB_START, STUB_END - STUB_START,
VM_READ | VM_MAYREAD | VM_EXEC | VM_READ | VM_MAYREAD | VM_EXEC |
VM_MAYEXEC | VM_DONTCOPY, pages); VM_MAYEXEC | VM_DONTCOPY,
mm->context.stub_pages);
if (err) { if (err) {
printk(KERN_ERR "install_special_mapping returned %d\n", err); printk(KERN_ERR "install_special_mapping returned %d\n", err);
goto out_free; goto out;
} }
return; return;
out_free:
kfree(pages);
out: out:
force_sigsegv(SIGSEGV, current); force_sigsegv(SIGSEGV, current);
} }
@ -151,8 +140,6 @@ void arch_exit_mmap(struct mm_struct *mm)
{ {
pte_t *pte; pte_t *pte;
if (mm->context.stub_pages != NULL)
kfree(mm->context.stub_pages);
pte = virt_to_pte(mm, STUB_CODE); pte = virt_to_pte(mm, STUB_CODE);
if (pte != NULL) if (pte != NULL)
pte_clear(mm, STUB_CODE, pte); pte_clear(mm, STUB_CODE, pte);

View File

@ -323,7 +323,6 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs)
} }
install_exec_creds(bprm); install_exec_creds(bprm);
current->flags &= ~PF_FORKNOEXEC;
if (N_MAGIC(ex) == OMAGIC) { if (N_MAGIC(ex) == OMAGIC) {
unsigned long text_addr, map_size; unsigned long text_addr, map_size;
@ -519,7 +518,8 @@ out:
static int __init init_aout_binfmt(void) 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) static void __exit exit_aout_binfmt(void)

View File

@ -87,7 +87,7 @@
static LIST_HEAD(service_processors); static LIST_HEAD(service_processors);
static struct inode *ibmasmfs_make_inode(struct super_block *sb, int mode); 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); 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) static int ibmasmfs_fill_super (struct super_block *sb, void *data, int silent)
{ {
struct inode *root; struct inode *root;
struct dentry *root_dentry;
sb->s_blocksize = PAGE_CACHE_SIZE; sb->s_blocksize = PAGE_CACHE_SIZE;
sb->s_blocksize_bits = PAGE_CACHE_SHIFT; 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_op = &simple_dir_inode_operations;
root->i_fop = ibmasmfs_dir_ops; root->i_fop = ibmasmfs_dir_ops;
root_dentry = d_alloc_root(root); sb->s_root = d_make_root(root);
if (!root_dentry) { if (!sb->s_root)
iput(root);
return -ENOMEM; return -ENOMEM;
}
sb->s_root = root_dentry;
ibmasmfs_create_files(sb, root_dentry); ibmasmfs_create_files(sb);
return 0; 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 list_head *entry;
struct service_processor *sp; 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 *dir;
struct dentry *remote_dir; struct dentry *remote_dir;
sp = list_entry(entry, struct service_processor, node); 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) if (!dir)
continue; continue;

View File

@ -211,18 +211,17 @@ static void __exit ibmasm_exit (void)
static int __init ibmasm_init(void) static int __init ibmasm_init(void)
{ {
int result; int result = pci_register_driver(&ibmasm_driver);
if (result)
return result;
result = ibmasmfs_register(); result = ibmasmfs_register();
if (result) { if (result) {
pci_unregister_driver(&ibmasm_driver);
err("Failed to register ibmasmfs file system"); err("Failed to register ibmasmfs file system");
return result; return result;
} }
result = pci_register_driver(&ibmasm_driver);
if (result) {
ibmasmfs_unregister();
return result;
}
ibmasm_register_panic_notifier(); ibmasm_register_panic_notifier();
info(DRIVER_DESC " version " DRIVER_VERSION " loaded"); info(DRIVER_DESC " version " DRIVER_VERSION " loaded");
return 0; return 0;

View File

@ -1685,7 +1685,7 @@ static int mmc_add_disk(struct mmc_blk_data *md)
if ((md->area_type & MMC_BLK_DATA_AREA_BOOT) && if ((md->area_type & MMC_BLK_DATA_AREA_BOOT) &&
card->ext_csd.boot_ro_lockable) { 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) if (card->ext_csd.boot_ro_lock & EXT_CSD_BOOT_WP_B_PWR_WP_DIS)
mode = S_IRUGO; mode = S_IRUGO;

View File

@ -516,7 +516,7 @@ static const struct file_operations bnad_debugfs_op_drvinfo = {
struct bnad_debugfs_entry { struct bnad_debugfs_entry {
const char *name; const char *name;
mode_t mode; umode_t mode;
const struct file_operations *fops; const struct file_operations *fops;
}; };

View File

@ -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) static int oprofilefs_fill_super(struct super_block *sb, void *data, int silent)
{ {
struct inode *root_inode; struct inode *root_inode;
struct dentry *root_dentry;
sb->s_blocksize = PAGE_CACHE_SIZE; sb->s_blocksize = PAGE_CACHE_SIZE;
sb->s_blocksize_bits = PAGE_CACHE_SHIFT; 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; return -ENOMEM;
root_inode->i_op = &simple_dir_inode_operations; root_inode->i_op = &simple_dir_inode_operations;
root_inode->i_fop = &simple_dir_operations; root_inode->i_fop = &simple_dir_operations;
root_dentry = d_alloc_root(root_inode); sb->s_root = d_make_root(root_inode);
if (!root_dentry) { if (!sb->s_root)
iput(root_inode);
return -ENOMEM; return -ENOMEM;
}
sb->s_root = root_dentry; oprofile_create_files(sb, sb->s_root);
oprofile_create_files(sb, root_dentry);
// FIXME: verify kill_litter_super removes our dentries // FIXME: verify kill_litter_super removes our dentries
return 0; return 0;

View File

@ -50,7 +50,6 @@
static const struct file_operations default_file_operations; static const struct file_operations default_file_operations;
static struct vfsmount *usbfs_mount; static struct vfsmount *usbfs_mount;
static int usbfs_mount_count; /* = 0 */ static int usbfs_mount_count; /* = 0 */
static int ignore_mount = 0;
static struct dentry *devices_usbfs_dentry; static struct dentry *devices_usbfs_dentry;
static int num_buses; /* = 0 */ 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, * i.e. it's a simple_pin_fs from create_special_files,
* then ignore it. * then ignore it.
*/ */
if (ignore_mount) if (*flags & MS_KERNMOUNT)
return 0; return 0;
if (parse_options(sb, data)) { 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) static int usbfs_fill_super(struct super_block *sb, void *data, int silent)
{ {
struct inode *inode; struct inode *inode;
struct dentry *root;
sb->s_blocksize = PAGE_CACHE_SIZE; sb->s_blocksize = PAGE_CACHE_SIZE;
sb->s_blocksize_bits = PAGE_CACHE_SHIFT; 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_op = &usbfs_ops;
sb->s_time_gran = 1; sb->s_time_gran = 1;
inode = usbfs_get_inode(sb, S_IFDIR | 0755, 0); inode = usbfs_get_inode(sb, S_IFDIR | 0755, 0);
sb->s_root = d_make_root(inode);
if (!inode) { if (!sb->s_root) {
dbg("%s: could not get inode!",__func__);
return -ENOMEM;
}
root = d_alloc_root(inode);
if (!root) {
dbg("%s: could not get root dentry!",__func__); dbg("%s: could not get root dentry!",__func__);
iput(inode);
return -ENOMEM; return -ENOMEM;
} }
sb->s_root = root;
return 0; return 0;
} }
@ -591,11 +581,6 @@ static int create_special_files (void)
struct dentry *parent; struct dentry *parent;
int retval; 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 */ /* create the devices special file */
retval = simple_pin_fs(&usb_fs_type, &usbfs_mount, &usbfs_mount_count); retval = simple_pin_fs(&usb_fs_type, &usbfs_mount, &usbfs_mount_count);
if (retval) { if (retval) {
@ -603,8 +588,6 @@ static int create_special_files (void)
goto exit; goto exit;
} }
ignore_mount = 0;
parent = usbfs_mount->mnt_root; parent = usbfs_mount->mnt_root;
devices_usbfs_dentry = fs_create_file ("devices", devices_usbfs_dentry = fs_create_file ("devices",
listmode | S_IFREG, parent, listmode | S_IFREG, parent,

View File

@ -1063,13 +1063,9 @@ static int ffs_sb_fill(struct super_block *sb, void *_data, int silent)
&simple_dir_operations, &simple_dir_operations,
&simple_dir_inode_operations, &simple_dir_inode_operations,
&data->perms); &data->perms);
if (unlikely(!inode)) sb->s_root = d_make_root(inode);
if (unlikely(!sb->s_root))
goto Enomem; goto Enomem;
sb->s_root = d_alloc_root(inode);
if (unlikely(!sb->s_root)) {
iput(inode);
goto Enomem;
}
/* EP0 file */ /* EP0 file */
if (unlikely(!ffs_sb_create_file(sb, "ep0", ffs, if (unlikely(!ffs_sb_create_file(sb, "ep0", ffs,

View File

@ -1571,20 +1571,18 @@ delegate:
static void destroy_ep_files (struct dev_data *dev) static void destroy_ep_files (struct dev_data *dev)
{ {
struct list_head *entry, *tmp;
DBG (dev, "%s %d\n", __func__, dev->state); DBG (dev, "%s %d\n", __func__, dev->state);
/* dev->state must prevent interference */ /* dev->state must prevent interference */
restart: restart:
spin_lock_irq (&dev->lock); spin_lock_irq (&dev->lock);
list_for_each_safe (entry, tmp, &dev->epfiles) { while (!list_empty(&dev->epfiles)) {
struct ep_data *ep; struct ep_data *ep;
struct inode *parent; struct inode *parent;
struct dentry *dentry; struct dentry *dentry;
/* break link to FS */ /* 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); list_del_init (&ep->epfiles);
dentry = ep->dentry; dentry = ep->dentry;
ep->dentry = NULL; ep->dentry = NULL;
@ -1607,8 +1605,7 @@ restart:
dput (dentry); dput (dentry);
mutex_unlock (&parent->i_mutex); mutex_unlock (&parent->i_mutex);
/* fds may still be open */ spin_lock_irq (&dev->lock);
goto restart;
} }
spin_unlock_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) if (!inode)
goto Enomem; goto Enomem;
inode->i_op = &simple_dir_inode_operations; inode->i_op = &simple_dir_inode_operations;
if (!(sb->s_root = d_alloc_root (inode))) { if (!(sb->s_root = d_make_root (inode)))
iput(inode);
goto Enomem; goto Enomem;
}
/* the ep0 file is named after the controller we expect; /* the ep0 file is named after the controller we expect;
* user mode code can use it for sanity checks, like we do. * user mode code can use it for sanity checks, like we do.

View File

@ -594,21 +594,21 @@ static int __init init_v9fs(void)
int err; int err;
pr_info("Installing v9fs 9p2000 file system support\n"); pr_info("Installing v9fs 9p2000 file system support\n");
/* TODO: Setup list of registered trasnport modules */ /* 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(); err = v9fs_cache_register();
if (err < 0) { if (err < 0) {
pr_err("Failed to register v9fs for caching\n"); pr_err("Failed to register v9fs for caching\n");
goto out_fs_unreg; return err;
} }
err = v9fs_sysfs_init(); err = v9fs_sysfs_init();
if (err < 0) { if (err < 0) {
pr_err("Failed to register with sysfs\n"); 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; goto out_sysfs_cleanup;
} }
@ -617,8 +617,8 @@ static int __init init_v9fs(void)
out_sysfs_cleanup: out_sysfs_cleanup:
v9fs_sysfs_cleanup(); v9fs_sysfs_cleanup();
out_fs_unreg: out_cache:
unregister_filesystem(&v9fs_fs_type); v9fs_cache_unregister();
return err; return err;
} }

View File

@ -155,9 +155,8 @@ static struct dentry *v9fs_mount(struct file_system_type *fs_type, int flags,
goto release_sb; goto release_sb;
} }
root = d_alloc_root(inode); root = d_make_root(inode);
if (!root) { if (!root) {
iput(inode);
retval = -ENOMEM; retval = -ENOMEM;
goto release_sb; goto release_sb;
} }

View File

@ -214,6 +214,7 @@ source "fs/minix/Kconfig"
source "fs/omfs/Kconfig" source "fs/omfs/Kconfig"
source "fs/hpfs/Kconfig" source "fs/hpfs/Kconfig"
source "fs/qnx4/Kconfig" source "fs/qnx4/Kconfig"
source "fs/qnx6/Kconfig"
source "fs/romfs/Kconfig" source "fs/romfs/Kconfig"
source "fs/pstore/Kconfig" source "fs/pstore/Kconfig"
source "fs/sysv/Kconfig" source "fs/sysv/Kconfig"

View File

@ -102,6 +102,7 @@ obj-$(CONFIG_UBIFS_FS) += ubifs/
obj-$(CONFIG_AFFS_FS) += affs/ obj-$(CONFIG_AFFS_FS) += affs/
obj-$(CONFIG_ROMFS_FS) += romfs/ obj-$(CONFIG_ROMFS_FS) += romfs/
obj-$(CONFIG_QNX4FS_FS) += qnx4/ obj-$(CONFIG_QNX4FS_FS) += qnx4/
obj-$(CONFIG_QNX6FS_FS) += qnx6/
obj-$(CONFIG_AUTOFS4_FS) += autofs4/ obj-$(CONFIG_AUTOFS4_FS) += autofs4/
obj-$(CONFIG_ADFS_FS) += adfs/ obj-$(CONFIG_ADFS_FS) += adfs/
obj-$(CONFIG_FUSE_FS) += fuse/ obj-$(CONFIG_FUSE_FS) += fuse/

View File

@ -483,10 +483,9 @@ static int adfs_fill_super(struct super_block *sb, void *data, int silent)
sb->s_d_op = &adfs_dentry_operations; sb->s_d_op = &adfs_dentry_operations;
root = adfs_iget(sb, &root_obj); root = adfs_iget(sb, &root_obj);
sb->s_root = d_alloc_root(root); sb->s_root = d_make_root(root);
if (!sb->s_root) { if (!sb->s_root) {
int i; int i;
iput(root);
for (i = 0; i < asb->s_map_size; i++) for (i = 0; i < asb->s_map_size; i++)
brelse(asb->s_map[i].dm_bh); brelse(asb->s_map[i].dm_bh);
kfree(asb->s_map); kfree(asb->s_map);

View File

@ -473,7 +473,7 @@ got_root:
root_inode = affs_iget(sb, root_block); root_inode = affs_iget(sb, root_block);
if (IS_ERR(root_inode)) { if (IS_ERR(root_inode)) {
ret = PTR_ERR(root_inode); ret = PTR_ERR(root_inode);
goto out_error_noinode; goto out_error;
} }
if (AFFS_SB(sb)->s_flags & SF_INTL) if (AFFS_SB(sb)->s_flags & SF_INTL)
@ -481,7 +481,7 @@ got_root:
else else
sb->s_d_op = &affs_dentry_operations; sb->s_d_op = &affs_dentry_operations;
sb->s_root = d_alloc_root(root_inode); sb->s_root = d_make_root(root_inode);
if (!sb->s_root) { if (!sb->s_root) {
printk(KERN_ERR "AFFS: Get root inode failed\n"); printk(KERN_ERR "AFFS: Get root inode failed\n");
goto out_error; goto out_error;
@ -494,9 +494,6 @@ got_root:
* Begin the cascaded cleanup ... * Begin the cascaded cleanup ...
*/ */
out_error: out_error:
if (root_inode)
iput(root_inode);
out_error_noinode:
kfree(sbi->s_bitmap); kfree(sbi->s_bitmap);
affs_brelse(root_bh); affs_brelse(root_bh);
kfree(sbi->s_prefix); kfree(sbi->s_prefix);

View File

@ -301,7 +301,6 @@ static int afs_fill_super(struct super_block *sb,
{ {
struct afs_super_info *as = sb->s_fs_info; struct afs_super_info *as = sb->s_fs_info;
struct afs_fid fid; struct afs_fid fid;
struct dentry *root = NULL;
struct inode *inode = NULL; struct inode *inode = NULL;
int ret; int ret;
@ -327,18 +326,16 @@ static int afs_fill_super(struct super_block *sb,
set_bit(AFS_VNODE_AUTOCELL, &AFS_FS_I(inode)->flags); set_bit(AFS_VNODE_AUTOCELL, &AFS_FS_I(inode)->flags);
ret = -ENOMEM; ret = -ENOMEM;
root = d_alloc_root(inode); sb->s_root = d_make_root(inode);
if (!root) if (!sb->s_root)
goto error; goto error;
sb->s_d_op = &afs_fs_dentry_operations; sb->s_d_op = &afs_fs_dentry_operations;
sb->s_root = root;
_leave(" = 0"); _leave(" = 0");
return 0; return 0;
error: error:
iput(inode);
_leave(" = %d", ret); _leave(" = %d", ret);
return ret; return ret;
} }

View File

@ -199,16 +199,7 @@ static int aio_setup_ring(struct kioctx *ctx)
static void ctx_rcu_free(struct rcu_head *head) static void ctx_rcu_free(struct rcu_head *head)
{ {
struct kioctx *ctx = container_of(head, struct kioctx, rcu_head); struct kioctx *ctx = container_of(head, struct kioctx, rcu_head);
unsigned nr_events = ctx->max_reqs;
kmem_cache_free(kioctx_cachep, ctx); kmem_cache_free(kioctx_cachep, ctx);
if (nr_events) {
spin_lock(&aio_nr_lock);
BUG_ON(aio_nr - nr_events > aio_nr);
aio_nr -= nr_events;
spin_unlock(&aio_nr_lock);
}
} }
/* __put_ioctx /* __put_ioctx
@ -217,13 +208,19 @@ static void ctx_rcu_free(struct rcu_head *head)
*/ */
static void __put_ioctx(struct kioctx *ctx) static void __put_ioctx(struct kioctx *ctx)
{ {
unsigned nr_events = ctx->max_reqs;
BUG_ON(ctx->reqs_active); BUG_ON(ctx->reqs_active);
cancel_delayed_work(&ctx->wq); cancel_delayed_work_sync(&ctx->wq);
cancel_work_sync(&ctx->wq.work);
aio_free_ring(ctx); aio_free_ring(ctx);
mmdrop(ctx->mm); mmdrop(ctx->mm);
ctx->mm = NULL; ctx->mm = NULL;
if (nr_events) {
spin_lock(&aio_nr_lock);
BUG_ON(aio_nr - nr_events > aio_nr);
aio_nr -= nr_events;
spin_unlock(&aio_nr_lock);
}
pr_debug("__put_ioctx: freeing %p\n", ctx); pr_debug("__put_ioctx: freeing %p\n", ctx);
call_rcu(&ctx->rcu_head, ctx_rcu_free); call_rcu(&ctx->rcu_head, ctx_rcu_free);
} }
@ -247,7 +244,7 @@ static struct kioctx *ioctx_alloc(unsigned nr_events)
{ {
struct mm_struct *mm; struct mm_struct *mm;
struct kioctx *ctx; struct kioctx *ctx;
int did_sync = 0; int err = -ENOMEM;
/* Prevent overflows */ /* Prevent overflows */
if ((nr_events > (0x10000000U / sizeof(struct io_event))) || if ((nr_events > (0x10000000U / sizeof(struct io_event))) ||
@ -256,7 +253,7 @@ static struct kioctx *ioctx_alloc(unsigned nr_events)
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
} }
if ((unsigned long)nr_events > aio_max_nr) if (!nr_events || (unsigned long)nr_events > aio_max_nr)
return ERR_PTR(-EAGAIN); return ERR_PTR(-EAGAIN);
ctx = kmem_cache_zalloc(kioctx_cachep, GFP_KERNEL); ctx = kmem_cache_zalloc(kioctx_cachep, GFP_KERNEL);
@ -280,25 +277,14 @@ static struct kioctx *ioctx_alloc(unsigned nr_events)
goto out_freectx; goto out_freectx;
/* limit the number of system wide aios */ /* limit the number of system wide aios */
do { spin_lock(&aio_nr_lock);
spin_lock_bh(&aio_nr_lock); if (aio_nr + nr_events > aio_max_nr ||
if (aio_nr + nr_events > aio_max_nr || aio_nr + nr_events < aio_nr) {
aio_nr + nr_events < aio_nr) spin_unlock(&aio_nr_lock);
ctx->max_reqs = 0;
else
aio_nr += ctx->max_reqs;
spin_unlock_bh(&aio_nr_lock);
if (ctx->max_reqs || did_sync)
break;
/* wait for rcu callbacks to have completed before giving up */
synchronize_rcu();
did_sync = 1;
ctx->max_reqs = nr_events;
} while (1);
if (ctx->max_reqs == 0)
goto out_cleanup; goto out_cleanup;
}
aio_nr += ctx->max_reqs;
spin_unlock(&aio_nr_lock);
/* now link into global list. */ /* now link into global list. */
spin_lock(&mm->ioctx_lock); spin_lock(&mm->ioctx_lock);
@ -310,16 +296,13 @@ static struct kioctx *ioctx_alloc(unsigned nr_events)
return ctx; return ctx;
out_cleanup: out_cleanup:
__put_ioctx(ctx); err = -EAGAIN;
return ERR_PTR(-EAGAIN); aio_free_ring(ctx);
out_freectx: out_freectx:
mmdrop(mm); mmdrop(mm);
kmem_cache_free(kioctx_cachep, ctx); kmem_cache_free(kioctx_cachep, ctx);
ctx = ERR_PTR(-ENOMEM); dprintk("aio: error allocating ioctx %d\n", err);
return ERR_PTR(err);
dprintk("aio: error allocating ioctx %p\n", ctx);
return ctx;
} }
/* aio_cancel_all /* aio_cancel_all
@ -407,10 +390,6 @@ void exit_aio(struct mm_struct *mm)
aio_cancel_all(ctx); aio_cancel_all(ctx);
wait_for_all_aios(ctx); wait_for_all_aios(ctx);
/*
* Ensure we don't leave the ctx on the aio_wq
*/
cancel_work_sync(&ctx->wq.work);
if (1 != atomic_read(&ctx->users)) if (1 != atomic_read(&ctx->users))
printk(KERN_DEBUG printk(KERN_DEBUG
@ -920,7 +899,7 @@ static void aio_kick_handler(struct work_struct *work)
unuse_mm(mm); unuse_mm(mm);
set_fs(oldfs); set_fs(oldfs);
/* /*
* we're in a worker thread already, don't use queue_delayed_work, * we're in a worker thread already; no point using non-zero delay
*/ */
if (requeue) if (requeue)
queue_delayed_work(aio_wq, &ctx->wq, 0); queue_delayed_work(aio_wq, &ctx->wq, 0);

View File

@ -39,19 +39,6 @@ static const struct dentry_operations anon_inodefs_dentry_operations = {
.d_dname = anon_inodefs_dname, .d_dname = anon_inodefs_dname,
}; };
static struct dentry *anon_inodefs_mount(struct file_system_type *fs_type,
int flags, const char *dev_name, void *data)
{
return mount_pseudo(fs_type, "anon_inode:", NULL,
&anon_inodefs_dentry_operations, ANON_INODE_FS_MAGIC);
}
static struct file_system_type anon_inode_fs_type = {
.name = "anon_inodefs",
.mount = anon_inodefs_mount,
.kill_sb = kill_anon_super,
};
/* /*
* nop .set_page_dirty method so that people can use .page_mkwrite on * nop .set_page_dirty method so that people can use .page_mkwrite on
* anon inodes. * anon inodes.
@ -65,6 +52,62 @@ static const struct address_space_operations anon_aops = {
.set_page_dirty = anon_set_page_dirty, .set_page_dirty = anon_set_page_dirty,
}; };
/*
* A single inode exists for all anon_inode files. Contrary to pipes,
* anon_inode inodes have no associated per-instance data, so we need
* only allocate one of them.
*/
static struct inode *anon_inode_mkinode(struct super_block *s)
{
struct inode *inode = new_inode_pseudo(s);
if (!inode)
return ERR_PTR(-ENOMEM);
inode->i_ino = get_next_ino();
inode->i_fop = &anon_inode_fops;
inode->i_mapping->a_ops = &anon_aops;
/*
* Mark the inode dirty from the very beginning,
* that way it will never be moved to the dirty
* list because mark_inode_dirty() will think
* that it already _is_ on the dirty list.
*/
inode->i_state = I_DIRTY;
inode->i_mode = S_IRUSR | S_IWUSR;
inode->i_uid = current_fsuid();
inode->i_gid = current_fsgid();
inode->i_flags |= S_PRIVATE;
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
return inode;
}
static struct dentry *anon_inodefs_mount(struct file_system_type *fs_type,
int flags, const char *dev_name, void *data)
{
struct dentry *root;
root = mount_pseudo(fs_type, "anon_inode:", NULL,
&anon_inodefs_dentry_operations, ANON_INODE_FS_MAGIC);
if (!IS_ERR(root)) {
struct super_block *s = root->d_sb;
anon_inode_inode = anon_inode_mkinode(s);
if (IS_ERR(anon_inode_inode)) {
dput(root);
deactivate_locked_super(s);
root = ERR_CAST(anon_inode_inode);
}
}
return root;
}
static struct file_system_type anon_inode_fs_type = {
.name = "anon_inodefs",
.mount = anon_inodefs_mount,
.kill_sb = kill_anon_super,
};
/** /**
* anon_inode_getfile - creates a new file instance by hooking it up to an * anon_inode_getfile - creates a new file instance by hooking it up to an
* anonymous inode, and a dentry that describe the "class" * anonymous inode, and a dentry that describe the "class"
@ -180,38 +223,6 @@ err_put_unused_fd:
} }
EXPORT_SYMBOL_GPL(anon_inode_getfd); EXPORT_SYMBOL_GPL(anon_inode_getfd);
/*
* A single inode exists for all anon_inode files. Contrary to pipes,
* anon_inode inodes have no associated per-instance data, so we need
* only allocate one of them.
*/
static struct inode *anon_inode_mkinode(void)
{
struct inode *inode = new_inode_pseudo(anon_inode_mnt->mnt_sb);
if (!inode)
return ERR_PTR(-ENOMEM);
inode->i_ino = get_next_ino();
inode->i_fop = &anon_inode_fops;
inode->i_mapping->a_ops = &anon_aops;
/*
* Mark the inode dirty from the very beginning,
* that way it will never be moved to the dirty
* list because mark_inode_dirty() will think
* that it already _is_ on the dirty list.
*/
inode->i_state = I_DIRTY;
inode->i_mode = S_IRUSR | S_IWUSR;
inode->i_uid = current_fsuid();
inode->i_gid = current_fsgid();
inode->i_flags |= S_PRIVATE;
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
return inode;
}
static int __init anon_inode_init(void) static int __init anon_inode_init(void)
{ {
int error; int error;
@ -224,16 +235,8 @@ static int __init anon_inode_init(void)
error = PTR_ERR(anon_inode_mnt); error = PTR_ERR(anon_inode_mnt);
goto err_unregister_filesystem; goto err_unregister_filesystem;
} }
anon_inode_inode = anon_inode_mkinode();
if (IS_ERR(anon_inode_inode)) {
error = PTR_ERR(anon_inode_inode);
goto err_mntput;
}
return 0; return 0;
err_mntput:
kern_unmount(anon_inode_mnt);
err_unregister_filesystem: err_unregister_filesystem:
unregister_filesystem(&anon_inode_fs_type); unregister_filesystem(&anon_inode_fs_type);
err_exit: err_exit:

View File

@ -31,11 +31,11 @@ static int __init init_autofs4_fs(void)
{ {
int err; int err;
autofs_dev_ioctl_init();
err = register_filesystem(&autofs_fs_type); err = register_filesystem(&autofs_fs_type);
if (err) if (err)
return err; autofs_dev_ioctl_exit();
autofs_dev_ioctl_init();
return err; return err;
} }

View File

@ -247,12 +247,9 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)
if (!ino) if (!ino)
goto fail_free; goto fail_free;
root_inode = autofs4_get_inode(s, S_IFDIR | 0755); root_inode = autofs4_get_inode(s, S_IFDIR | 0755);
if (!root_inode) root = d_make_root(root_inode);
goto fail_ino;
root = d_alloc_root(root_inode);
if (!root) if (!root)
goto fail_iput; goto fail_ino;
pipe = NULL; pipe = NULL;
root->d_fsdata = ino; root->d_fsdata = ino;
@ -317,9 +314,6 @@ fail_fput:
fail_dput: fail_dput:
dput(root); dput(root);
goto fail_free; goto fail_free;
fail_iput:
printk("autofs: get root dentry failed\n");
iput(root_inode);
fail_ino: fail_ino:
kfree(ino); kfree(ino);
fail_free: fail_free:

View File

@ -852,9 +852,8 @@ befs_fill_super(struct super_block *sb, void *data, int silent)
ret = PTR_ERR(root); ret = PTR_ERR(root);
goto unacquire_priv_sbp; goto unacquire_priv_sbp;
} }
sb->s_root = d_alloc_root(root); sb->s_root = d_make_root(root);
if (!sb->s_root) { if (!sb->s_root) {
iput(root);
befs_error(sb, "get root inode failed"); befs_error(sb, "get root inode failed");
goto unacquire_priv_sbp; goto unacquire_priv_sbp;
} }

View File

@ -367,9 +367,8 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
ret = PTR_ERR(inode); ret = PTR_ERR(inode);
goto out2; goto out2;
} }
s->s_root = d_alloc_root(inode); s->s_root = d_make_root(inode);
if (!s->s_root) { if (!s->s_root) {
iput(inode);
ret = -ENOMEM; ret = -ENOMEM;
goto out2; goto out2;
} }

View File

@ -267,7 +267,6 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
} }
install_exec_creds(bprm); install_exec_creds(bprm);
current->flags &= ~PF_FORKNOEXEC;
if (N_MAGIC(ex) == OMAGIC) { if (N_MAGIC(ex) == OMAGIC) {
unsigned long text_addr, map_size; unsigned long text_addr, map_size;
@ -454,7 +453,8 @@ out:
static int __init init_aout_binfmt(void) 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) static void __exit exit_aout_binfmt(void)

View File

@ -712,7 +712,6 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
goto out_free_dentry; goto out_free_dentry;
/* OK, This is the point of no return */ /* OK, This is the point of no return */
current->flags &= ~PF_FORKNOEXEC;
current->mm->def_flags = def_flags; current->mm->def_flags = def_flags;
/* Do this immediately, since STACK_TOP as used in setup_arg_pages /* Do this immediately, since STACK_TOP as used in setup_arg_pages
@ -934,7 +933,6 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
#endif /* ARCH_HAS_SETUP_ADDITIONAL_PAGES */ #endif /* ARCH_HAS_SETUP_ADDITIONAL_PAGES */
install_exec_creds(bprm); install_exec_creds(bprm);
current->flags &= ~PF_FORKNOEXEC;
retval = create_elf_tables(bprm, &loc->elf_ex, retval = create_elf_tables(bprm, &loc->elf_ex,
load_addr, interp_load_addr); load_addr, interp_load_addr);
if (retval < 0) { if (retval < 0) {
@ -2077,7 +2075,8 @@ out:
static int __init init_elf_binfmt(void) static int __init init_elf_binfmt(void)
{ {
return register_binfmt(&elf_format); register_binfmt(&elf_format);
return 0;
} }
static void __exit exit_elf_binfmt(void) static void __exit exit_elf_binfmt(void)

View File

@ -91,7 +91,8 @@ static struct linux_binfmt elf_fdpic_format = {
static int __init init_elf_fdpic_binfmt(void) static int __init init_elf_fdpic_binfmt(void)
{ {
return register_binfmt(&elf_fdpic_format); register_binfmt(&elf_fdpic_format);
return 0;
} }
static void __exit exit_elf_fdpic_binfmt(void) static void __exit exit_elf_fdpic_binfmt(void)
@ -334,8 +335,6 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm,
current->mm->context.exec_fdpic_loadmap = 0; current->mm->context.exec_fdpic_loadmap = 0;
current->mm->context.interp_fdpic_loadmap = 0; current->mm->context.interp_fdpic_loadmap = 0;
current->flags &= ~PF_FORKNOEXEC;
#ifdef CONFIG_MMU #ifdef CONFIG_MMU
elf_fdpic_arch_lay_out_mm(&exec_params, elf_fdpic_arch_lay_out_mm(&exec_params,
&interp_params, &interp_params,
@ -413,7 +412,6 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm,
#endif #endif
install_exec_creds(bprm); install_exec_creds(bprm);
current->flags &= ~PF_FORKNOEXEC;
if (create_elf_fdpic_tables(bprm, current->mm, if (create_elf_fdpic_tables(bprm, current->mm,
&exec_params, &interp_params) < 0) &exec_params, &interp_params) < 0)
goto error_kill; goto error_kill;

View File

@ -100,7 +100,8 @@ static struct linux_binfmt em86_format = {
static int __init init_em86_binfmt(void) static int __init init_em86_binfmt(void)
{ {
return register_binfmt(&em86_format); register_binfmt(&em86_format);
return 0;
} }
static void __exit exit_em86_binfmt(void) static void __exit exit_em86_binfmt(void)

View File

@ -902,7 +902,6 @@ static int load_flat_binary(struct linux_binprm * bprm, struct pt_regs * regs)
libinfo.lib_list[j].start_data:UNLOADED_LIB; libinfo.lib_list[j].start_data:UNLOADED_LIB;
install_exec_creds(bprm); install_exec_creds(bprm);
current->flags &= ~PF_FORKNOEXEC;
set_binfmt(&flat_format); set_binfmt(&flat_format);
@ -950,7 +949,8 @@ static int load_flat_binary(struct linux_binprm * bprm, struct pt_regs * regs)
static int __init init_flat_binfmt(void) static int __init init_flat_binfmt(void)
{ {
return register_binfmt(&flat_format); register_binfmt(&flat_format);
return 0;
} }
/****************************************************************************/ /****************************************************************************/

View File

@ -726,11 +726,8 @@ static struct file_system_type bm_fs_type = {
static int __init init_misc_binfmt(void) static int __init init_misc_binfmt(void)
{ {
int err = register_filesystem(&bm_fs_type); int err = register_filesystem(&bm_fs_type);
if (!err) { if (!err)
err = insert_binfmt(&misc_format); insert_binfmt(&misc_format);
if (err)
unregister_filesystem(&bm_fs_type);
}
return err; return err;
} }

View File

@ -105,7 +105,8 @@ static struct linux_binfmt script_format = {
static int __init init_script_binfmt(void) static int __init init_script_binfmt(void)
{ {
return register_binfmt(&script_format); register_binfmt(&script_format);
return 0;
} }
static void __exit exit_script_binfmt(void) static void __exit exit_script_binfmt(void)

View File

@ -225,7 +225,6 @@ load_som_binary(struct linux_binprm * bprm, struct pt_regs * regs)
goto out_free; goto out_free;
/* OK, This is the point of no return */ /* OK, This is the point of no return */
current->flags &= ~PF_FORKNOEXEC;
current->personality = PER_HPUX; current->personality = PER_HPUX;
setup_new_exec(bprm); setup_new_exec(bprm);
@ -289,7 +288,8 @@ static int load_som_library(struct file *f)
static int __init init_som_binfmt(void) static int __init init_som_binfmt(void)
{ {
return register_binfmt(&som_format); register_binfmt(&som_format);
return 0;
} }
static void __exit exit_som_binfmt(void) static void __exit exit_som_binfmt(void)

View File

@ -629,7 +629,6 @@ static int btrfs_fill_super(struct super_block *sb,
void *data, int silent) void *data, int silent)
{ {
struct inode *inode; struct inode *inode;
struct dentry *root_dentry;
struct btrfs_fs_info *fs_info = btrfs_sb(sb); struct btrfs_fs_info *fs_info = btrfs_sb(sb);
struct btrfs_key key; struct btrfs_key key;
int err; int err;
@ -660,15 +659,12 @@ static int btrfs_fill_super(struct super_block *sb,
goto fail_close; goto fail_close;
} }
root_dentry = d_alloc_root(inode); sb->s_root = d_make_root(inode);
if (!root_dentry) { if (!sb->s_root) {
iput(inode);
err = -ENOMEM; err = -ENOMEM;
goto fail_close; goto fail_close;
} }
sb->s_root = root_dentry;
save_mount_options(sb, data); save_mount_options(sb, data);
cleancache_init_fs(sb); cleancache_init_fs(sb);
sb->s_flags |= MS_ACTIVE; sb->s_flags |= MS_ACTIVE;

View File

@ -646,7 +646,8 @@ lookup_again:
* (this is used to keep track of culling, and atimes are only * (this is used to keep track of culling, and atimes are only
* updated by read, write and readdir but not lookup or * updated by read, write and readdir but not lookup or
* open) */ * open) */
touch_atime(cache->mnt, next); path.dentry = next;
touch_atime(&path);
} }
/* open a file interface onto a data file */ /* open a file interface onto a data file */

View File

@ -655,9 +655,8 @@ static struct dentry *open_root_dentry(struct ceph_fs_client *fsc,
dout("open_root_inode success\n"); dout("open_root_inode success\n");
if (ceph_ino(inode) == CEPH_INO_ROOT && if (ceph_ino(inode) == CEPH_INO_ROOT &&
fsc->sb->s_root == NULL) { fsc->sb->s_root == NULL) {
root = d_alloc_root(inode); root = d_make_root(inode);
if (!root) { if (!root) {
iput(inode);
root = ERR_PTR(-ENOMEM); root = ERR_PTR(-ENOMEM);
goto out; goto out;
} }

View File

@ -119,12 +119,10 @@ cifs_read_super(struct super_block *sb)
if (IS_ERR(inode)) { if (IS_ERR(inode)) {
rc = PTR_ERR(inode); rc = PTR_ERR(inode);
inode = NULL;
goto out_no_root; goto out_no_root;
} }
sb->s_root = d_alloc_root(inode); sb->s_root = d_make_root(inode);
if (!sb->s_root) { if (!sb->s_root) {
rc = -ENOMEM; rc = -ENOMEM;
goto out_no_root; goto out_no_root;
@ -147,9 +145,6 @@ cifs_read_super(struct super_block *sb)
out_no_root: out_no_root:
cERROR(1, "cifs_read_super: get root inode failed"); cERROR(1, "cifs_read_super: get root inode failed");
if (inode)
iput(inode);
return rc; return rc;
} }

View File

@ -208,13 +208,12 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)
if (IS_ERR(root)) { if (IS_ERR(root)) {
error = PTR_ERR(root); error = PTR_ERR(root);
printk("Failure of coda_cnode_make for root: error %d\n", error); printk("Failure of coda_cnode_make for root: error %d\n", error);
root = NULL;
goto error; goto error;
} }
printk("coda_read_super: rootinode is %ld dev %s\n", printk("coda_read_super: rootinode is %ld dev %s\n",
root->i_ino, root->i_sb->s_id); root->i_ino, root->i_sb->s_id);
sb->s_root = d_alloc_root(root); sb->s_root = d_make_root(root);
if (!sb->s_root) { if (!sb->s_root) {
error = -EINVAL; error = -EINVAL;
goto error; goto error;
@ -222,9 +221,6 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)
return 0; return 0;
error: error:
if (root)
iput(root);
mutex_lock(&vc->vc_mutex); mutex_lock(&vc->vc_mutex);
bdi_destroy(&vc->bdi); bdi_destroy(&vc->bdi);
vc->vc_sb = NULL; vc->vc_sb = NULL;

View File

@ -58,12 +58,11 @@ struct configfs_dirent {
extern struct mutex configfs_symlink_mutex; extern struct mutex configfs_symlink_mutex;
extern spinlock_t configfs_dirent_lock; extern spinlock_t configfs_dirent_lock;
extern struct vfsmount * configfs_mount;
extern struct kmem_cache *configfs_dir_cachep; extern struct kmem_cache *configfs_dir_cachep;
extern int configfs_is_root(struct config_item *item); extern int configfs_is_root(struct config_item *item);
extern struct inode * configfs_new_inode(umode_t mode, struct configfs_dirent *); extern struct inode * configfs_new_inode(umode_t mode, struct configfs_dirent *, struct super_block *);
extern int configfs_create(struct dentry *, umode_t mode, int (*init)(struct inode *)); extern int configfs_create(struct dentry *, umode_t mode, int (*init)(struct inode *));
extern int configfs_inode_init(void); extern int configfs_inode_init(void);
extern void configfs_inode_exit(void); extern void configfs_inode_exit(void);
@ -80,15 +79,15 @@ extern const unsigned char * configfs_get_name(struct configfs_dirent *sd);
extern void configfs_drop_dentry(struct configfs_dirent *sd, struct dentry *parent); extern void configfs_drop_dentry(struct configfs_dirent *sd, struct dentry *parent);
extern int configfs_setattr(struct dentry *dentry, struct iattr *iattr); extern int configfs_setattr(struct dentry *dentry, struct iattr *iattr);
extern int configfs_pin_fs(void); extern struct dentry *configfs_pin_fs(void);
extern void configfs_release_fs(void); extern void configfs_release_fs(void);
extern struct rw_semaphore configfs_rename_sem; extern struct rw_semaphore configfs_rename_sem;
extern struct super_block * configfs_sb;
extern const struct file_operations configfs_dir_operations; extern const struct file_operations configfs_dir_operations;
extern const struct file_operations configfs_file_operations; extern const struct file_operations configfs_file_operations;
extern const struct file_operations bin_fops; extern const struct file_operations bin_fops;
extern const struct inode_operations configfs_dir_inode_operations; extern const struct inode_operations configfs_dir_inode_operations;
extern const struct inode_operations configfs_root_inode_operations;
extern const struct inode_operations configfs_symlink_inode_operations; extern const struct inode_operations configfs_symlink_inode_operations;
extern const struct dentry_operations configfs_dentry_ops; extern const struct dentry_operations configfs_dentry_ops;

View File

@ -264,11 +264,13 @@ static int init_symlink(struct inode * inode)
return 0; return 0;
} }
static int create_dir(struct config_item * k, struct dentry * p, static int create_dir(struct config_item *k, struct dentry *d)
struct dentry * d)
{ {
int error; int error;
umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO; umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO;
struct dentry *p = d->d_parent;
BUG_ON(!k);
error = configfs_dirent_exists(p->d_fsdata, d->d_name.name); error = configfs_dirent_exists(p->d_fsdata, d->d_name.name);
if (!error) if (!error)
@ -304,19 +306,7 @@ static int create_dir(struct config_item * k, struct dentry * p,
static int configfs_create_dir(struct config_item * item, struct dentry *dentry) static int configfs_create_dir(struct config_item * item, struct dentry *dentry)
{ {
struct dentry * parent; int error = create_dir(item, dentry);
int error = 0;
BUG_ON(!item);
if (item->ci_parent)
parent = item->ci_parent->ci_dentry;
else if (configfs_mount)
parent = configfs_mount->mnt_root;
else
return -EFAULT;
error = create_dir(item,parent,dentry);
if (!error) if (!error)
item->ci_dentry = dentry; item->ci_dentry = dentry;
return error; return error;
@ -1079,23 +1069,24 @@ int configfs_depend_item(struct configfs_subsystem *subsys,
int ret; int ret;
struct configfs_dirent *p, *root_sd, *subsys_sd = NULL; struct configfs_dirent *p, *root_sd, *subsys_sd = NULL;
struct config_item *s_item = &subsys->su_group.cg_item; struct config_item *s_item = &subsys->su_group.cg_item;
struct dentry *root;
/* /*
* Pin the configfs filesystem. This means we can safely access * Pin the configfs filesystem. This means we can safely access
* the root of the configfs filesystem. * the root of the configfs filesystem.
*/ */
ret = configfs_pin_fs(); root = configfs_pin_fs();
if (ret) if (IS_ERR(root))
return ret; return PTR_ERR(root);
/* /*
* Next, lock the root directory. We're going to check that the * Next, lock the root directory. We're going to check that the
* subsystem is really registered, and so we need to lock out * subsystem is really registered, and so we need to lock out
* configfs_[un]register_subsystem(). * configfs_[un]register_subsystem().
*/ */
mutex_lock(&configfs_sb->s_root->d_inode->i_mutex); mutex_lock(&root->d_inode->i_mutex);
root_sd = configfs_sb->s_root->d_fsdata; root_sd = root->d_fsdata;
list_for_each_entry(p, &root_sd->s_children, s_sibling) { list_for_each_entry(p, &root_sd->s_children, s_sibling) {
if (p->s_type & CONFIGFS_DIR) { if (p->s_type & CONFIGFS_DIR) {
@ -1129,7 +1120,7 @@ int configfs_depend_item(struct configfs_subsystem *subsys,
out_unlock_dirent_lock: out_unlock_dirent_lock:
spin_unlock(&configfs_dirent_lock); spin_unlock(&configfs_dirent_lock);
out_unlock_fs: out_unlock_fs:
mutex_unlock(&configfs_sb->s_root->d_inode->i_mutex); mutex_unlock(&root->d_inode->i_mutex);
/* /*
* If we succeeded, the fs is pinned via other methods. If not, * If we succeeded, the fs is pinned via other methods. If not,
@ -1183,11 +1174,6 @@ static int configfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode
struct module *subsys_owner = NULL, *new_item_owner = NULL; struct module *subsys_owner = NULL, *new_item_owner = NULL;
char *name; char *name;
if (dentry->d_parent == configfs_sb->s_root) {
ret = -EPERM;
goto out;
}
sd = dentry->d_parent->d_fsdata; sd = dentry->d_parent->d_fsdata;
/* /*
@ -1359,9 +1345,6 @@ static int configfs_rmdir(struct inode *dir, struct dentry *dentry)
struct module *subsys_owner = NULL, *dead_item_owner = NULL; struct module *subsys_owner = NULL, *dead_item_owner = NULL;
int ret; int ret;
if (dentry->d_parent == configfs_sb->s_root)
return -EPERM;
sd = dentry->d_fsdata; sd = dentry->d_fsdata;
if (sd->s_type & CONFIGFS_USET_DEFAULT) if (sd->s_type & CONFIGFS_USET_DEFAULT)
return -EPERM; return -EPERM;
@ -1459,6 +1442,11 @@ const struct inode_operations configfs_dir_inode_operations = {
.setattr = configfs_setattr, .setattr = configfs_setattr,
}; };
const struct inode_operations configfs_root_inode_operations = {
.lookup = configfs_lookup,
.setattr = configfs_setattr,
};
#if 0 #if 0
int configfs_rename_dir(struct config_item * item, const char *new_name) int configfs_rename_dir(struct config_item * item, const char *new_name)
{ {
@ -1546,6 +1534,7 @@ static inline unsigned char dt_type(struct configfs_dirent *sd)
static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir) static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
{ {
struct dentry *dentry = filp->f_path.dentry; struct dentry *dentry = filp->f_path.dentry;
struct super_block *sb = dentry->d_sb;
struct configfs_dirent * parent_sd = dentry->d_fsdata; struct configfs_dirent * parent_sd = dentry->d_fsdata;
struct configfs_dirent *cursor = filp->private_data; struct configfs_dirent *cursor = filp->private_data;
struct list_head *p, *q = &cursor->s_sibling; struct list_head *p, *q = &cursor->s_sibling;
@ -1608,7 +1597,7 @@ static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir
ino = inode->i_ino; ino = inode->i_ino;
spin_unlock(&configfs_dirent_lock); spin_unlock(&configfs_dirent_lock);
if (!inode) if (!inode)
ino = iunique(configfs_sb, 2); ino = iunique(sb, 2);
if (filldir(dirent, name, len, filp->f_pos, ino, if (filldir(dirent, name, len, filp->f_pos, ino,
dt_type(next)) < 0) dt_type(next)) < 0)
@ -1680,27 +1669,27 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys)
struct config_group *group = &subsys->su_group; struct config_group *group = &subsys->su_group;
struct qstr name; struct qstr name;
struct dentry *dentry; struct dentry *dentry;
struct dentry *root;
struct configfs_dirent *sd; struct configfs_dirent *sd;
err = configfs_pin_fs(); root = configfs_pin_fs();
if (err) if (IS_ERR(root))
return err; return PTR_ERR(root);
if (!group->cg_item.ci_name) if (!group->cg_item.ci_name)
group->cg_item.ci_name = group->cg_item.ci_namebuf; group->cg_item.ci_name = group->cg_item.ci_namebuf;
sd = configfs_sb->s_root->d_fsdata; sd = root->d_fsdata;
link_group(to_config_group(sd->s_element), group); link_group(to_config_group(sd->s_element), group);
mutex_lock_nested(&configfs_sb->s_root->d_inode->i_mutex, mutex_lock_nested(&root->d_inode->i_mutex, I_MUTEX_PARENT);
I_MUTEX_PARENT);
name.name = group->cg_item.ci_name; name.name = group->cg_item.ci_name;
name.len = strlen(name.name); name.len = strlen(name.name);
name.hash = full_name_hash(name.name, name.len); name.hash = full_name_hash(name.name, name.len);
err = -ENOMEM; err = -ENOMEM;
dentry = d_alloc(configfs_sb->s_root, &name); dentry = d_alloc(root, &name);
if (dentry) { if (dentry) {
d_add(dentry, NULL); d_add(dentry, NULL);
@ -1717,7 +1706,7 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys)
} }
} }
mutex_unlock(&configfs_sb->s_root->d_inode->i_mutex); mutex_unlock(&root->d_inode->i_mutex);
if (err) { if (err) {
unlink_group(group); unlink_group(group);
@ -1731,13 +1720,14 @@ void configfs_unregister_subsystem(struct configfs_subsystem *subsys)
{ {
struct config_group *group = &subsys->su_group; struct config_group *group = &subsys->su_group;
struct dentry *dentry = group->cg_item.ci_dentry; struct dentry *dentry = group->cg_item.ci_dentry;
struct dentry *root = dentry->d_sb->s_root;
if (dentry->d_parent != configfs_sb->s_root) { if (dentry->d_parent != root) {
printk(KERN_ERR "configfs: Tried to unregister non-subsystem!\n"); printk(KERN_ERR "configfs: Tried to unregister non-subsystem!\n");
return; return;
} }
mutex_lock_nested(&configfs_sb->s_root->d_inode->i_mutex, mutex_lock_nested(&root->d_inode->i_mutex,
I_MUTEX_PARENT); I_MUTEX_PARENT);
mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_CHILD); mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_CHILD);
mutex_lock(&configfs_symlink_mutex); mutex_lock(&configfs_symlink_mutex);
@ -1754,7 +1744,7 @@ void configfs_unregister_subsystem(struct configfs_subsystem *subsys)
d_delete(dentry); d_delete(dentry);
mutex_unlock(&configfs_sb->s_root->d_inode->i_mutex); mutex_unlock(&root->d_inode->i_mutex);
dput(dentry); dput(dentry);

View File

@ -44,8 +44,6 @@
static struct lock_class_key default_group_class[MAX_LOCK_DEPTH]; static struct lock_class_key default_group_class[MAX_LOCK_DEPTH];
#endif #endif
extern struct super_block * configfs_sb;
static const struct address_space_operations configfs_aops = { static const struct address_space_operations configfs_aops = {
.readpage = simple_readpage, .readpage = simple_readpage,
.write_begin = simple_write_begin, .write_begin = simple_write_begin,
@ -132,9 +130,10 @@ static inline void set_inode_attr(struct inode * inode, struct iattr * iattr)
inode->i_ctime = iattr->ia_ctime; inode->i_ctime = iattr->ia_ctime;
} }
struct inode *configfs_new_inode(umode_t mode, struct configfs_dirent * sd) struct inode *configfs_new_inode(umode_t mode, struct configfs_dirent *sd,
struct super_block *s)
{ {
struct inode * inode = new_inode(configfs_sb); struct inode * inode = new_inode(s);
if (inode) { if (inode) {
inode->i_ino = get_next_ino(); inode->i_ino = get_next_ino();
inode->i_mapping->a_ops = &configfs_aops; inode->i_mapping->a_ops = &configfs_aops;
@ -188,36 +187,35 @@ static void configfs_set_inode_lock_class(struct configfs_dirent *sd,
int configfs_create(struct dentry * dentry, umode_t mode, int (*init)(struct inode *)) int configfs_create(struct dentry * dentry, umode_t mode, int (*init)(struct inode *))
{ {
int error = 0; int error = 0;
struct inode * inode = NULL; struct inode *inode = NULL;
if (dentry) { struct configfs_dirent *sd;
if (!dentry->d_inode) { struct inode *p_inode;
struct configfs_dirent *sd = dentry->d_fsdata;
if ((inode = configfs_new_inode(mode, sd))) {
if (dentry->d_parent && dentry->d_parent->d_inode) {
struct inode *p_inode = dentry->d_parent->d_inode;
p_inode->i_mtime = p_inode->i_ctime = CURRENT_TIME;
}
configfs_set_inode_lock_class(sd, inode);
goto Proceed;
}
else
error = -ENOMEM;
} else
error = -EEXIST;
} else
error = -ENOENT;
goto Done;
Proceed: if (!dentry)
if (init) return -ENOENT;
if (dentry->d_inode)
return -EEXIST;
sd = dentry->d_fsdata;
inode = configfs_new_inode(mode, sd, dentry->d_sb);
if (!inode)
return -ENOMEM;
p_inode = dentry->d_parent->d_inode;
p_inode->i_mtime = p_inode->i_ctime = CURRENT_TIME;
configfs_set_inode_lock_class(sd, inode);
if (init) {
error = init(inode); error = init(inode);
if (!error) { if (error) {
d_instantiate(dentry, inode); iput(inode);
if (S_ISDIR(mode) || S_ISLNK(mode)) return error;
dget(dentry); /* pin link and directory dentries in core */ }
} else }
iput(inode); d_instantiate(dentry, inode);
Done: if (S_ISDIR(mode) || S_ISLNK(mode))
dget(dentry); /* pin link and directory dentries in core */
return error; return error;
} }

View File

@ -37,8 +37,7 @@
/* Random magic number */ /* Random magic number */
#define CONFIGFS_MAGIC 0x62656570 #define CONFIGFS_MAGIC 0x62656570
struct vfsmount * configfs_mount = NULL; static struct vfsmount *configfs_mount = NULL;
struct super_block * configfs_sb = NULL;
struct kmem_cache *configfs_dir_cachep; struct kmem_cache *configfs_dir_cachep;
static int configfs_mnt_count = 0; static int configfs_mnt_count = 0;
@ -77,12 +76,11 @@ static int configfs_fill_super(struct super_block *sb, void *data, int silent)
sb->s_magic = CONFIGFS_MAGIC; sb->s_magic = CONFIGFS_MAGIC;
sb->s_op = &configfs_ops; sb->s_op = &configfs_ops;
sb->s_time_gran = 1; sb->s_time_gran = 1;
configfs_sb = sb;
inode = configfs_new_inode(S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO, inode = configfs_new_inode(S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO,
&configfs_root); &configfs_root, sb);
if (inode) { if (inode) {
inode->i_op = &configfs_dir_inode_operations; inode->i_op = &configfs_root_inode_operations;
inode->i_fop = &configfs_dir_operations; inode->i_fop = &configfs_dir_operations;
/* directory inodes start off with i_nlink == 2 (for "." entry) */ /* directory inodes start off with i_nlink == 2 (for "." entry) */
inc_nlink(inode); inc_nlink(inode);
@ -91,10 +89,9 @@ static int configfs_fill_super(struct super_block *sb, void *data, int silent)
return -ENOMEM; return -ENOMEM;
} }
root = d_alloc_root(inode); root = d_make_root(inode);
if (!root) { if (!root) {
pr_debug("%s: could not get root dentry!\n",__func__); pr_debug("%s: could not get root dentry!\n",__func__);
iput(inode);
return -ENOMEM; return -ENOMEM;
} }
config_group_init(&configfs_root_group); config_group_init(&configfs_root_group);
@ -118,10 +115,11 @@ static struct file_system_type configfs_fs_type = {
.kill_sb = kill_litter_super, .kill_sb = kill_litter_super,
}; };
int configfs_pin_fs(void) struct dentry *configfs_pin_fs(void)
{ {
return simple_pin_fs(&configfs_fs_type, &configfs_mount, int err = simple_pin_fs(&configfs_fs_type, &configfs_mount,
&configfs_mnt_count); &configfs_mnt_count);
return err ? ERR_PTR(err) : configfs_mount->mnt_root;
} }
void configfs_release_fs(void) void configfs_release_fs(void)

View File

@ -110,13 +110,13 @@ out:
static int get_target(const char *symname, struct path *path, static int get_target(const char *symname, struct path *path,
struct config_item **target) struct config_item **target, struct super_block *sb)
{ {
int ret; int ret;
ret = kern_path(symname, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, path); ret = kern_path(symname, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, path);
if (!ret) { if (!ret) {
if (path->dentry->d_sb == configfs_sb) { if (path->dentry->d_sb == sb) {
*target = configfs_get_config_item(path->dentry); *target = configfs_get_config_item(path->dentry);
if (!*target) { if (!*target) {
ret = -ENOENT; ret = -ENOENT;
@ -141,10 +141,6 @@ int configfs_symlink(struct inode *dir, struct dentry *dentry, const char *symna
struct config_item *target_item = NULL; struct config_item *target_item = NULL;
struct config_item_type *type; struct config_item_type *type;
ret = -EPERM; /* What lack-of-symlink returns */
if (dentry->d_parent == configfs_sb->s_root)
goto out;
sd = dentry->d_parent->d_fsdata; sd = dentry->d_parent->d_fsdata;
/* /*
* Fake invisibility if dir belongs to a group/default groups hierarchy * Fake invisibility if dir belongs to a group/default groups hierarchy
@ -162,7 +158,7 @@ int configfs_symlink(struct inode *dir, struct dentry *dentry, const char *symna
!type->ct_item_ops->allow_link) !type->ct_item_ops->allow_link)
goto out_put; goto out_put;
ret = get_target(symname, &path, &target_item); ret = get_target(symname, &path, &target_item, dentry->d_sb);
if (ret) if (ret)
goto out_put; goto out_put;
@ -198,8 +194,6 @@ int configfs_unlink(struct inode *dir, struct dentry *dentry)
if (!(sd->s_type & CONFIGFS_ITEM_LINK)) if (!(sd->s_type & CONFIGFS_ITEM_LINK))
goto out; goto out;
BUG_ON(dentry->d_parent == configfs_sb->s_root);
sl = sd->s_element; sl = sd->s_element;
parent_item = configfs_get_config_item(dentry->d_parent); parent_item = configfs_get_config_item(dentry->d_parent);

View File

@ -318,11 +318,9 @@ static int cramfs_fill_super(struct super_block *sb, void *data, int silent)
root = get_cramfs_inode(sb, &super.root, 0); root = get_cramfs_inode(sb, &super.root, 0);
if (IS_ERR(root)) if (IS_ERR(root))
goto out; goto out;
sb->s_root = d_alloc_root(root); sb->s_root = d_make_root(root);
if (!sb->s_root) { if (!sb->s_root)
iput(root);
goto out; goto out;
}
return 0; return 0;
out: out:
kfree(sbi); kfree(sbi);

View File

@ -1466,30 +1466,6 @@ struct dentry *d_instantiate_unique(struct dentry *entry, struct inode *inode)
EXPORT_SYMBOL(d_instantiate_unique); EXPORT_SYMBOL(d_instantiate_unique);
/**
* d_alloc_root - allocate root dentry
* @root_inode: inode to allocate the root for
*
* Allocate a root ("/") dentry for the inode given. The inode is
* instantiated and returned. %NULL is returned if there is insufficient
* memory or the inode passed is %NULL.
*/
struct dentry * d_alloc_root(struct inode * root_inode)
{
struct dentry *res = NULL;
if (root_inode) {
static const struct qstr name = { .name = "/", .len = 1 };
res = __d_alloc(root_inode->i_sb, &name);
if (res)
d_instantiate(res, root_inode);
}
return res;
}
EXPORT_SYMBOL(d_alloc_root);
struct dentry *d_make_root(struct inode *root_inode) struct dentry *d_make_root(struct inode *root_inode)
{ {
struct dentry *res = NULL; struct dentry *res = NULL;

View File

@ -611,7 +611,7 @@ static const struct file_operations fops_regset32 = {
* %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling * %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling
* code. * code.
*/ */
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 dentry *parent,
struct debugfs_regset32 *regset) struct debugfs_regset32 *regset)
{ {

View File

@ -374,12 +374,11 @@ devpts_fill_super(struct super_block *s, void *data, int silent)
inode->i_fop = &simple_dir_operations; inode->i_fop = &simple_dir_operations;
set_nlink(inode, 2); set_nlink(inode, 2);
s->s_root = d_alloc_root(inode); s->s_root = d_make_root(inode);
if (s->s_root) if (s->s_root)
return 0; return 0;
printk(KERN_ERR "devpts: get root dentry failed\n"); printk(KERN_ERR "devpts: get root dentry failed\n");
iput(inode);
fail: fail:
return -ENOMEM; return -ENOMEM;

View File

@ -48,8 +48,7 @@ static ssize_t ecryptfs_read_update_atime(struct kiocb *iocb,
unsigned long nr_segs, loff_t pos) unsigned long nr_segs, loff_t pos)
{ {
ssize_t rc; ssize_t rc;
struct dentry *lower_dentry; struct path lower;
struct vfsmount *lower_vfsmount;
struct file *file = iocb->ki_filp; struct file *file = iocb->ki_filp;
rc = generic_file_aio_read(iocb, iov, nr_segs, pos); rc = generic_file_aio_read(iocb, iov, nr_segs, pos);
@ -60,9 +59,9 @@ static ssize_t ecryptfs_read_update_atime(struct kiocb *iocb,
if (-EIOCBQUEUED == rc) if (-EIOCBQUEUED == rc)
rc = wait_on_sync_kiocb(iocb); rc = wait_on_sync_kiocb(iocb);
if (rc >= 0) { if (rc >= 0) {
lower_dentry = ecryptfs_dentry_to_lower(file->f_path.dentry); lower.dentry = ecryptfs_dentry_to_lower(file->f_path.dentry);
lower_vfsmount = ecryptfs_dentry_to_lower_mnt(file->f_path.dentry); lower.mnt = ecryptfs_dentry_to_lower_mnt(file->f_path.dentry);
touch_atime(lower_vfsmount, lower_dentry); touch_atime(&lower);
} }
return rc; return rc;
} }

View File

@ -550,9 +550,8 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags
if (IS_ERR(inode)) if (IS_ERR(inode))
goto out_free; goto out_free;
s->s_root = d_alloc_root(inode); s->s_root = d_make_root(inode);
if (!s->s_root) { if (!s->s_root) {
iput(inode);
rc = -ENOMEM; rc = -ENOMEM;
goto out_free; goto out_free;
} }
@ -795,15 +794,10 @@ static int __init ecryptfs_init(void)
"Failed to allocate one or more kmem_cache objects\n"); "Failed to allocate one or more kmem_cache objects\n");
goto out; goto out;
} }
rc = register_filesystem(&ecryptfs_fs_type);
if (rc) {
printk(KERN_ERR "Failed to register filesystem\n");
goto out_free_kmem_caches;
}
rc = do_sysfs_registration(); rc = do_sysfs_registration();
if (rc) { if (rc) {
printk(KERN_ERR "sysfs registration failed\n"); printk(KERN_ERR "sysfs registration failed\n");
goto out_unregister_filesystem; goto out_free_kmem_caches;
} }
rc = ecryptfs_init_kthread(); rc = ecryptfs_init_kthread();
if (rc) { if (rc) {
@ -824,19 +818,24 @@ static int __init ecryptfs_init(void)
"rc = [%d]\n", rc); "rc = [%d]\n", rc);
goto out_release_messaging; goto out_release_messaging;
} }
rc = register_filesystem(&ecryptfs_fs_type);
if (rc) {
printk(KERN_ERR "Failed to register filesystem\n");
goto out_destroy_crypto;
}
if (ecryptfs_verbosity > 0) if (ecryptfs_verbosity > 0)
printk(KERN_CRIT "eCryptfs verbosity set to %d. Secret values " printk(KERN_CRIT "eCryptfs verbosity set to %d. Secret values "
"will be written to the syslog!\n", ecryptfs_verbosity); "will be written to the syslog!\n", ecryptfs_verbosity);
goto out; goto out;
out_destroy_crypto:
ecryptfs_destroy_crypto();
out_release_messaging: out_release_messaging:
ecryptfs_release_messaging(); ecryptfs_release_messaging();
out_destroy_kthread: out_destroy_kthread:
ecryptfs_destroy_kthread(); ecryptfs_destroy_kthread();
out_do_sysfs_unregistration: out_do_sysfs_unregistration:
do_sysfs_unregistration(); do_sysfs_unregistration();
out_unregister_filesystem:
unregister_filesystem(&ecryptfs_fs_type);
out_free_kmem_caches: out_free_kmem_caches:
ecryptfs_free_kmem_caches(); ecryptfs_free_kmem_caches();
out: out:

View File

@ -184,7 +184,6 @@ static int ecryptfs_show_options(struct seq_file *m, struct dentry *root)
const struct super_operations ecryptfs_sops = { const struct super_operations ecryptfs_sops = {
.alloc_inode = ecryptfs_alloc_inode, .alloc_inode = ecryptfs_alloc_inode,
.destroy_inode = ecryptfs_destroy_inode, .destroy_inode = ecryptfs_destroy_inode,
.drop_inode = generic_drop_inode,
.statfs = ecryptfs_statfs, .statfs = ecryptfs_statfs,
.remount_fs = NULL, .remount_fs = NULL,
.evict_inode = ecryptfs_evict_inode, .evict_inode = ecryptfs_evict_inode,

View File

@ -317,10 +317,9 @@ static int efs_fill_super(struct super_block *s, void *d, int silent)
goto out_no_fs; goto out_no_fs;
} }
s->s_root = d_alloc_root(root); s->s_root = d_make_root(root);
if (!(s->s_root)) { if (!(s->s_root)) {
printk(KERN_ERR "EFS: get root dentry failed\n"); printk(KERN_ERR "EFS: get root dentry failed\n");
iput(root);
ret = -ENOMEM; ret = -ENOMEM;
goto out_no_fs; goto out_no_fs;
} }

View File

@ -81,15 +81,13 @@ static atomic_t call_count = ATOMIC_INIT(1);
static LIST_HEAD(formats); static LIST_HEAD(formats);
static DEFINE_RWLOCK(binfmt_lock); static DEFINE_RWLOCK(binfmt_lock);
int __register_binfmt(struct linux_binfmt * fmt, int insert) void __register_binfmt(struct linux_binfmt * fmt, int insert)
{ {
if (!fmt) BUG_ON(!fmt);
return -EINVAL;
write_lock(&binfmt_lock); write_lock(&binfmt_lock);
insert ? list_add(&fmt->lh, &formats) : insert ? list_add(&fmt->lh, &formats) :
list_add_tail(&fmt->lh, &formats); list_add_tail(&fmt->lh, &formats);
write_unlock(&binfmt_lock); write_unlock(&binfmt_lock);
return 0;
} }
EXPORT_SYMBOL(__register_binfmt); EXPORT_SYMBOL(__register_binfmt);
@ -1115,7 +1113,7 @@ int flush_old_exec(struct linux_binprm * bprm)
bprm->mm = NULL; /* We're using it now */ bprm->mm = NULL; /* We're using it now */
set_fs(USER_DS); set_fs(USER_DS);
current->flags &= ~(PF_RANDOMIZE | PF_KTHREAD); current->flags &= ~(PF_RANDOMIZE | PF_FORKNOEXEC | PF_KTHREAD);
flush_thread(); flush_thread();
current->personality &= ~bprm->per_clear; current->personality &= ~bprm->per_clear;

View File

@ -143,9 +143,6 @@ static int exofs_link(struct dentry *old_dentry, struct inode *dir,
{ {
struct inode *inode = old_dentry->d_inode; struct inode *inode = old_dentry->d_inode;
if (inode->i_nlink >= EXOFS_LINK_MAX)
return -EMLINK;
inode->i_ctime = CURRENT_TIME; inode->i_ctime = CURRENT_TIME;
inode_inc_link_count(inode); inode_inc_link_count(inode);
ihold(inode); ihold(inode);
@ -156,10 +153,7 @@ static int exofs_link(struct dentry *old_dentry, struct inode *dir,
static int exofs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) static int exofs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
{ {
struct inode *inode; struct inode *inode;
int err = -EMLINK; int err;
if (dir->i_nlink >= EXOFS_LINK_MAX)
goto out;
inode_inc_link_count(dir); inode_inc_link_count(dir);
@ -275,11 +269,6 @@ static int exofs_rename(struct inode *old_dir, struct dentry *old_dentry,
if (err) if (err)
goto out_dir; goto out_dir;
} else { } else {
if (dir_de) {
err = -EMLINK;
if (new_dir->i_nlink >= EXOFS_LINK_MAX)
goto out_dir;
}
err = exofs_add_link(new_dentry, old_inode); err = exofs_add_link(new_dentry, old_inode);
if (err) if (err)
goto out_dir; goto out_dir;

View File

@ -754,6 +754,7 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent)
sb->s_blocksize = EXOFS_BLKSIZE; sb->s_blocksize = EXOFS_BLKSIZE;
sb->s_blocksize_bits = EXOFS_BLKSHIFT; sb->s_blocksize_bits = EXOFS_BLKSHIFT;
sb->s_maxbytes = MAX_LFS_FILESIZE; sb->s_maxbytes = MAX_LFS_FILESIZE;
sb->s_max_links = EXOFS_LINK_MAX;
atomic_set(&sbi->s_curr_pending, 0); atomic_set(&sbi->s_curr_pending, 0);
sb->s_bdev = NULL; sb->s_bdev = NULL;
sb->s_dev = 0; sb->s_dev = 0;
@ -818,9 +819,8 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent)
ret = PTR_ERR(root); ret = PTR_ERR(root);
goto free_sbi; goto free_sbi;
} }
sb->s_root = d_alloc_root(root); sb->s_root = d_make_root(root);
if (!sb->s_root) { if (!sb->s_root) {
iput(root);
EXOFS_ERR("ERROR: get root inode failed\n"); EXOFS_ERR("ERROR: get root inode failed\n");
ret = -ENOMEM; ret = -ENOMEM;
goto free_sbi; goto free_sbi;

View File

@ -195,9 +195,6 @@ static int ext2_link (struct dentry * old_dentry, struct inode * dir,
struct inode *inode = old_dentry->d_inode; struct inode *inode = old_dentry->d_inode;
int err; int err;
if (inode->i_nlink >= EXT2_LINK_MAX)
return -EMLINK;
dquot_initialize(dir); dquot_initialize(dir);
inode->i_ctime = CURRENT_TIME_SEC; inode->i_ctime = CURRENT_TIME_SEC;
@ -217,10 +214,7 @@ static int ext2_link (struct dentry * old_dentry, struct inode * dir,
static int ext2_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode) static int ext2_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode)
{ {
struct inode * inode; struct inode * inode;
int err = -EMLINK; int err;
if (dir->i_nlink >= EXT2_LINK_MAX)
goto out;
dquot_initialize(dir); dquot_initialize(dir);
@ -346,11 +340,6 @@ static int ext2_rename (struct inode * old_dir, struct dentry * old_dentry,
drop_nlink(new_inode); drop_nlink(new_inode);
inode_dec_link_count(new_inode); inode_dec_link_count(new_inode);
} else { } else {
if (dir_de) {
err = -EMLINK;
if (new_dir->i_nlink >= EXT2_LINK_MAX)
goto out_dir;
}
err = ext2_add_link(new_dentry, old_inode); err = ext2_add_link(new_dentry, old_inode);
if (err) if (err)
goto out_dir; goto out_dir;

View File

@ -919,6 +919,7 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
} }
sb->s_maxbytes = ext2_max_size(sb->s_blocksize_bits); sb->s_maxbytes = ext2_max_size(sb->s_blocksize_bits);
sb->s_max_links = EXT2_LINK_MAX;
if (le32_to_cpu(es->s_rev_level) == EXT2_GOOD_OLD_REV) { if (le32_to_cpu(es->s_rev_level) == EXT2_GOOD_OLD_REV) {
sbi->s_inode_size = EXT2_GOOD_OLD_INODE_SIZE; sbi->s_inode_size = EXT2_GOOD_OLD_INODE_SIZE;
@ -1087,9 +1088,8 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
goto failed_mount3; goto failed_mount3;
} }
sb->s_root = d_alloc_root(root); sb->s_root = d_make_root(root);
if (!sb->s_root) { if (!sb->s_root) {
iput(root);
ext2_msg(sb, KERN_ERR, "error: get root inode failed"); ext2_msg(sb, KERN_ERR, "error: get root inode failed");
ret = -ENOMEM; ret = -ENOMEM;
goto failed_mount3; goto failed_mount3;

View File

@ -2046,10 +2046,9 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
ext3_msg(sb, KERN_ERR, "error: corrupt root inode, run e2fsck"); ext3_msg(sb, KERN_ERR, "error: corrupt root inode, run e2fsck");
goto failed_mount3; goto failed_mount3;
} }
sb->s_root = d_alloc_root(root); sb->s_root = d_make_root(root);
if (!sb->s_root) { if (!sb->s_root) {
ext3_msg(sb, KERN_ERR, "error: get root dentry failed"); ext3_msg(sb, KERN_ERR, "error: get root dentry failed");
iput(root);
ret = -ENOMEM; ret = -ENOMEM;
goto failed_mount3; goto failed_mount3;
} }

View File

@ -3735,9 +3735,8 @@ no_journal:
iput(root); iput(root);
goto failed_mount4; goto failed_mount4;
} }
sb->s_root = d_alloc_root(root); sb->s_root = d_make_root(root);
if (!sb->s_root) { if (!sb->s_root) {
iput(root);
ext4_msg(sb, KERN_ERR, "get root dentry failed"); ext4_msg(sb, KERN_ERR, "get root dentry failed");
ret = -ENOMEM; ret = -ENOMEM;
goto failed_mount4; goto failed_mount4;
@ -5056,6 +5055,9 @@ static int __init ext4_init_fs(void)
{ {
int i, err; int i, err;
ext4_li_info = NULL;
mutex_init(&ext4_li_mtx);
ext4_check_flag_values(); ext4_check_flag_values();
for (i = 0; i < EXT4_WQ_HASH_SZ; i++) { for (i = 0; i < EXT4_WQ_HASH_SZ; i++) {
@ -5094,8 +5096,6 @@ static int __init ext4_init_fs(void)
if (err) if (err)
goto out; goto out;
ext4_li_info = NULL;
mutex_init(&ext4_li_mtx);
return 0; return 0;
out: out:
unregister_as_ext2(); unregister_as_ext2();

View File

@ -1496,11 +1496,13 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
root_inode->i_ino = MSDOS_ROOT_INO; root_inode->i_ino = MSDOS_ROOT_INO;
root_inode->i_version = 1; root_inode->i_version = 1;
error = fat_read_root(root_inode); error = fat_read_root(root_inode);
if (error < 0) if (error < 0) {
iput(root_inode);
goto out_fail; goto out_fail;
}
error = -ENOMEM; error = -ENOMEM;
insert_inode_hash(root_inode); insert_inode_hash(root_inode);
sb->s_root = d_alloc_root(root_inode); sb->s_root = d_make_root(root_inode);
if (!sb->s_root) { if (!sb->s_root) {
fat_msg(sb, KERN_ERR, "get root inode failed"); fat_msg(sb, KERN_ERR, "get root inode failed");
goto out_fail; goto out_fail;
@ -1516,8 +1518,6 @@ out_invalid:
out_fail: out_fail:
if (fat_inode) if (fat_inode)
iput(fat_inode); iput(fat_inode);
if (root_inode)
iput(root_inode);
unload_nls(sbi->nls_io); unload_nls(sbi->nls_io);
unload_nls(sbi->nls_disk); unload_nls(sbi->nls_disk);
if (sbi->options.iocharset != fat_default_iocharset) if (sbi->options.iocharset != fat_default_iocharset)

View File

@ -204,7 +204,7 @@ EXPORT_SYMBOL(alloc_file);
* to write to @file, along with access to write through * to write to @file, along with access to write through
* its vfsmount. * its vfsmount.
*/ */
void drop_file_write_access(struct file *file) static void drop_file_write_access(struct file *file)
{ {
struct vfsmount *mnt = file->f_path.mnt; struct vfsmount *mnt = file->f_path.mnt;
struct dentry *dentry = file->f_path.dentry; struct dentry *dentry = file->f_path.dentry;
@ -219,7 +219,6 @@ void drop_file_write_access(struct file *file)
mnt_drop_write(mnt); mnt_drop_write(mnt);
file_release_write(file); file_release_write(file);
} }
EXPORT_SYMBOL_GPL(drop_file_write_access);
/* the real guts of fput() - releasing the last reference to file /* the real guts of fput() - releasing the last reference to file
*/ */

View File

@ -224,9 +224,8 @@ static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent)
ret = PTR_ERR(root); ret = PTR_ERR(root);
goto out; goto out;
} }
sbp->s_root = d_alloc_root(root); sbp->s_root = d_make_root(root);
if (!sbp->s_root) { if (!sbp->s_root) {
iput(root);
printk(KERN_WARNING "vxfs: unable to get root dentry.\n"); printk(KERN_WARNING "vxfs: unable to get root dentry.\n");
goto out_free_ilist; goto out_free_ilist;
} }

View File

@ -26,11 +26,11 @@ void set_fs_root(struct fs_struct *fs, struct path *path)
{ {
struct path old_root; struct path old_root;
path_get_longterm(path);
spin_lock(&fs->lock); spin_lock(&fs->lock);
write_seqcount_begin(&fs->seq); write_seqcount_begin(&fs->seq);
old_root = fs->root; old_root = fs->root;
fs->root = *path; fs->root = *path;
path_get_longterm(path);
write_seqcount_end(&fs->seq); write_seqcount_end(&fs->seq);
spin_unlock(&fs->lock); spin_unlock(&fs->lock);
if (old_root.dentry) if (old_root.dentry)
@ -45,11 +45,11 @@ void set_fs_pwd(struct fs_struct *fs, struct path *path)
{ {
struct path old_pwd; struct path old_pwd;
path_get_longterm(path);
spin_lock(&fs->lock); spin_lock(&fs->lock);
write_seqcount_begin(&fs->seq); write_seqcount_begin(&fs->seq);
old_pwd = fs->pwd; old_pwd = fs->pwd;
fs->pwd = *path; fs->pwd = *path;
path_get_longterm(path);
write_seqcount_end(&fs->seq); write_seqcount_end(&fs->seq);
spin_unlock(&fs->lock); spin_unlock(&fs->lock);
@ -57,6 +57,14 @@ void set_fs_pwd(struct fs_struct *fs, struct path *path)
path_put_longterm(&old_pwd); path_put_longterm(&old_pwd);
} }
static inline int replace_path(struct path *p, const struct path *old, const struct path *new)
{
if (likely(p->dentry != old->dentry || p->mnt != old->mnt))
return 0;
*p = *new;
return 1;
}
void chroot_fs_refs(struct path *old_root, struct path *new_root) void chroot_fs_refs(struct path *old_root, struct path *new_root)
{ {
struct task_struct *g, *p; struct task_struct *g, *p;
@ -68,21 +76,16 @@ void chroot_fs_refs(struct path *old_root, struct path *new_root)
task_lock(p); task_lock(p);
fs = p->fs; fs = p->fs;
if (fs) { if (fs) {
int hits = 0;
spin_lock(&fs->lock); spin_lock(&fs->lock);
write_seqcount_begin(&fs->seq); write_seqcount_begin(&fs->seq);
if (fs->root.dentry == old_root->dentry hits += replace_path(&fs->root, old_root, new_root);
&& fs->root.mnt == old_root->mnt) { hits += replace_path(&fs->pwd, old_root, new_root);
path_get_longterm(new_root);
fs->root = *new_root;
count++;
}
if (fs->pwd.dentry == old_root->dentry
&& fs->pwd.mnt == old_root->mnt) {
path_get_longterm(new_root);
fs->pwd = *new_root;
count++;
}
write_seqcount_end(&fs->seq); write_seqcount_end(&fs->seq);
while (hits--) {
count++;
path_get_longterm(new_root);
}
spin_unlock(&fs->lock); spin_unlock(&fs->lock);
} }
task_unlock(p); task_unlock(p);
@ -107,10 +110,8 @@ void exit_fs(struct task_struct *tsk)
int kill; int kill;
task_lock(tsk); task_lock(tsk);
spin_lock(&fs->lock); spin_lock(&fs->lock);
write_seqcount_begin(&fs->seq);
tsk->fs = NULL; tsk->fs = NULL;
kill = !--fs->users; kill = !--fs->users;
write_seqcount_end(&fs->seq);
spin_unlock(&fs->lock); spin_unlock(&fs->lock);
task_unlock(tsk); task_unlock(tsk);
if (kill) if (kill)

View File

@ -988,14 +988,9 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
err = -ENOMEM; err = -ENOMEM;
root = fuse_get_root_inode(sb, d.rootmode); root = fuse_get_root_inode(sb, d.rootmode);
if (!root) root_dentry = d_make_root(root);
if (!root_dentry)
goto err_put_conn; goto err_put_conn;
root_dentry = d_alloc_root(root);
if (!root_dentry) {
iput(root);
goto err_put_conn;
}
/* only now - we want root dentry with NULL ->d_op */ /* only now - we want root dentry with NULL ->d_op */
sb->s_d_op = &fuse_dentry_operations; sb->s_d_op = &fuse_dentry_operations;

View File

@ -431,10 +431,9 @@ static int gfs2_lookup_root(struct super_block *sb, struct dentry **dptr,
fs_err(sdp, "can't read in %s inode: %ld\n", name, PTR_ERR(inode)); fs_err(sdp, "can't read in %s inode: %ld\n", name, PTR_ERR(inode));
return PTR_ERR(inode); return PTR_ERR(inode);
} }
dentry = d_alloc_root(inode); dentry = d_make_root(inode);
if (!dentry) { if (!dentry) {
fs_err(sdp, "can't alloc %s dentry\n", name); fs_err(sdp, "can't alloc %s dentry\n", name);
iput(inode);
return -ENOMEM; return -ENOMEM;
} }
*dptr = dentry; *dptr = dentry;

View File

@ -430,15 +430,13 @@ static int hfs_fill_super(struct super_block *sb, void *data, int silent)
sb->s_d_op = &hfs_dentry_operations; sb->s_d_op = &hfs_dentry_operations;
res = -ENOMEM; res = -ENOMEM;
sb->s_root = d_alloc_root(root_inode); sb->s_root = d_make_root(root_inode);
if (!sb->s_root) if (!sb->s_root)
goto bail_iput; goto bail_no_root;
/* everything's okay */ /* everything's okay */
return 0; return 0;
bail_iput:
iput(root_inode);
bail_no_root: bail_no_root:
printk(KERN_ERR "hfs: get root inode failed.\n"); printk(KERN_ERR "hfs: get root inode failed.\n");
bail: bail:

View File

@ -316,6 +316,11 @@ static inline unsigned short hfsplus_min_io_size(struct super_block *sb)
#define HFSPLUS_IOC_EXT2_SETFLAGS FS_IOC_SETFLAGS #define HFSPLUS_IOC_EXT2_SETFLAGS FS_IOC_SETFLAGS
/*
* hfs+-specific ioctl for making the filesystem bootable
*/
#define HFSPLUS_IOC_BLESS _IO('h', 0x80)
/* /*
* Functions in any *.c used in other files * Functions in any *.c used in other files
*/ */

View File

@ -117,7 +117,7 @@ struct hfsplus_vh {
__be32 write_count; __be32 write_count;
__be64 encodings_bmp; __be64 encodings_bmp;
u8 finder_info[32]; u32 finder_info[8];
struct hfsplus_fork_raw alloc_file; struct hfsplus_fork_raw alloc_file;
struct hfsplus_fork_raw ext_file; struct hfsplus_fork_raw ext_file;

View File

@ -193,6 +193,7 @@ static struct dentry *hfsplus_file_lookup(struct inode *dir,
mutex_init(&hip->extents_lock); mutex_init(&hip->extents_lock);
hip->extent_state = 0; hip->extent_state = 0;
hip->flags = 0; hip->flags = 0;
hip->userflags = 0;
set_bit(HFSPLUS_I_RSRC, &hip->flags); set_bit(HFSPLUS_I_RSRC, &hip->flags);
err = hfs_find_init(HFSPLUS_SB(sb)->cat_tree, &fd); err = hfs_find_init(HFSPLUS_SB(sb)->cat_tree, &fd);
@ -400,6 +401,7 @@ struct inode *hfsplus_new_inode(struct super_block *sb, umode_t mode)
atomic_set(&hip->opencnt, 0); atomic_set(&hip->opencnt, 0);
hip->extent_state = 0; hip->extent_state = 0;
hip->flags = 0; hip->flags = 0;
hip->userflags = 0;
memset(hip->first_extents, 0, sizeof(hfsplus_extent_rec)); memset(hip->first_extents, 0, sizeof(hfsplus_extent_rec));
memset(hip->cached_extents, 0, sizeof(hfsplus_extent_rec)); memset(hip->cached_extents, 0, sizeof(hfsplus_extent_rec));
hip->alloc_blocks = 0; hip->alloc_blocks = 0;

View File

@ -20,6 +20,38 @@
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include "hfsplus_fs.h" #include "hfsplus_fs.h"
/*
* "Blessing" an HFS+ filesystem writes metadata to the superblock informing
* the platform firmware which file to boot from
*/
static int hfsplus_ioctl_bless(struct file *file, int __user *user_flags)
{
struct dentry *dentry = file->f_path.dentry;
struct inode *inode = dentry->d_inode;
struct hfsplus_sb_info *sbi = HFSPLUS_SB(inode->i_sb);
struct hfsplus_vh *vh = sbi->s_vhdr;
struct hfsplus_vh *bvh = sbi->s_backup_vhdr;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
mutex_lock(&sbi->vh_mutex);
/* Directory containing the bootable system */
vh->finder_info[0] = bvh->finder_info[0] =
cpu_to_be32(parent_ino(dentry));
/* Bootloader */
vh->finder_info[1] = bvh->finder_info[1] = cpu_to_be32(inode->i_ino);
/* Per spec, the OS X system folder - same as finder_info[0] here */
vh->finder_info[5] = bvh->finder_info[5] =
cpu_to_be32(parent_ino(dentry));
mutex_unlock(&sbi->vh_mutex);
return 0;
}
static int hfsplus_ioctl_getflags(struct file *file, int __user *user_flags) static int hfsplus_ioctl_getflags(struct file *file, int __user *user_flags)
{ {
struct inode *inode = file->f_path.dentry->d_inode; struct inode *inode = file->f_path.dentry->d_inode;
@ -108,6 +140,8 @@ long hfsplus_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
return hfsplus_ioctl_getflags(file, argp); return hfsplus_ioctl_getflags(file, argp);
case HFSPLUS_IOC_EXT2_SETFLAGS: case HFSPLUS_IOC_EXT2_SETFLAGS:
return hfsplus_ioctl_setflags(file, argp); return hfsplus_ioctl_setflags(file, argp);
case HFSPLUS_IOC_BLESS:
return hfsplus_ioctl_bless(file, argp);
default: default:
return -ENOTTY; return -ENOTTY;
} }

View File

@ -465,6 +465,13 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent)
goto out_put_alloc_file; goto out_put_alloc_file;
} }
sb->s_d_op = &hfsplus_dentry_operations;
sb->s_root = d_make_root(root);
if (!sb->s_root) {
err = -ENOMEM;
goto out_put_alloc_file;
}
str.len = sizeof(HFSP_HIDDENDIR_NAME) - 1; str.len = sizeof(HFSP_HIDDENDIR_NAME) - 1;
str.name = HFSP_HIDDENDIR_NAME; str.name = HFSP_HIDDENDIR_NAME;
err = hfs_find_init(sbi->cat_tree, &fd); err = hfs_find_init(sbi->cat_tree, &fd);
@ -515,13 +522,6 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent)
} }
} }
sb->s_d_op = &hfsplus_dentry_operations;
sb->s_root = d_alloc_root(root);
if (!sb->s_root) {
err = -ENOMEM;
goto out_put_hidden_dir;
}
unload_nls(sbi->nls); unload_nls(sbi->nls);
sbi->nls = nls; sbi->nls = nls;
return 0; return 0;
@ -529,7 +529,8 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent)
out_put_hidden_dir: out_put_hidden_dir:
iput(sbi->hidden_dir); iput(sbi->hidden_dir);
out_put_root: out_put_root:
iput(root); dput(sb->s_root);
sb->s_root = NULL;
out_put_alloc_file: out_put_alloc_file:
iput(sbi->alloc_file); iput(sbi->alloc_file);
out_close_cat_tree: out_close_cat_tree:

View File

@ -966,9 +966,9 @@ static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent)
} }
err = -ENOMEM; err = -ENOMEM;
sb->s_root = d_alloc_root(root_inode); sb->s_root = d_make_root(root_inode);
if (sb->s_root == NULL) if (sb->s_root == NULL)
goto out_put; goto out;
return 0; return 0;

View File

@ -625,11 +625,9 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent)
hpfs_init_inode(root); hpfs_init_inode(root);
hpfs_read_inode(root); hpfs_read_inode(root);
unlock_new_inode(root); unlock_new_inode(root);
s->s_root = d_alloc_root(root); s->s_root = d_make_root(root);
if (!s->s_root) { if (!s->s_root)
iput(root);
goto bail0; goto bail0;
}
/* /*
* find the root directory's . pointer & finish filling in the inode * find the root directory's . pointer & finish filling in the inode

View File

@ -726,17 +726,12 @@ static int hppfs_fill_super(struct super_block *sb, void *d, int silent)
err = -ENOMEM; err = -ENOMEM;
root_inode = get_inode(sb, dget(proc_mnt->mnt_root)); root_inode = get_inode(sb, dget(proc_mnt->mnt_root));
if (!root_inode) sb->s_root = d_make_root(root_inode);
goto out_mntput;
sb->s_root = d_alloc_root(root_inode);
if (!sb->s_root) if (!sb->s_root)
goto out_iput; goto out_mntput;
return 0; return 0;
out_iput:
iput(root_inode);
out_mntput: out_mntput:
mntput(proc_mnt); mntput(proc_mnt);
out: out:

View File

@ -831,8 +831,6 @@ bad_val:
static int static int
hugetlbfs_fill_super(struct super_block *sb, void *data, int silent) hugetlbfs_fill_super(struct super_block *sb, void *data, int silent)
{ {
struct inode * inode;
struct dentry * root;
int ret; int ret;
struct hugetlbfs_config config; struct hugetlbfs_config config;
struct hugetlbfs_sb_info *sbinfo; struct hugetlbfs_sb_info *sbinfo;
@ -865,16 +863,9 @@ hugetlbfs_fill_super(struct super_block *sb, void *data, int silent)
sb->s_magic = HUGETLBFS_MAGIC; sb->s_magic = HUGETLBFS_MAGIC;
sb->s_op = &hugetlbfs_ops; sb->s_op = &hugetlbfs_ops;
sb->s_time_gran = 1; sb->s_time_gran = 1;
inode = hugetlbfs_get_root(sb, &config); sb->s_root = d_make_root(hugetlbfs_get_root(sb, &config));
if (!inode) if (!sb->s_root)
goto out_free; goto out_free;
root = d_alloc_root(inode);
if (!root) {
iput(inode);
goto out_free;
}
sb->s_root = root;
return 0; return 0;
out_free: out_free:
kfree(sbinfo); kfree(sbinfo);

View File

@ -2,29 +2,19 @@
* (C) 1997 Linus Torvalds * (C) 1997 Linus Torvalds
* (C) 1999 Andrea Arcangeli <andrea@suse.de> (dynamic inode allocation) * (C) 1999 Andrea Arcangeli <andrea@suse.de> (dynamic inode allocation)
*/ */
#include <linux/export.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/dcache.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/writeback.h>
#include <linux/module.h>
#include <linux/backing-dev.h> #include <linux/backing-dev.h>
#include <linux/wait.h>
#include <linux/rwsem.h>
#include <linux/hash.h> #include <linux/hash.h>
#include <linux/swap.h> #include <linux/swap.h>
#include <linux/security.h> #include <linux/security.h>
#include <linux/pagemap.h>
#include <linux/cdev.h> #include <linux/cdev.h>
#include <linux/bootmem.h> #include <linux/bootmem.h>
#include <linux/fsnotify.h> #include <linux/fsnotify.h>
#include <linux/mount.h> #include <linux/mount.h>
#include <linux/async.h>
#include <linux/posix_acl.h> #include <linux/posix_acl.h>
#include <linux/prefetch.h> #include <linux/prefetch.h>
#include <linux/ima.h>
#include <linux/cred.h>
#include <linux/buffer_head.h> /* for inode_has_buffers */ #include <linux/buffer_head.h> /* for inode_has_buffers */
#include <linux/ratelimit.h> #include <linux/ratelimit.h>
#include "internal.h" #include "internal.h"
@ -1368,17 +1358,6 @@ int generic_delete_inode(struct inode *inode)
} }
EXPORT_SYMBOL(generic_delete_inode); EXPORT_SYMBOL(generic_delete_inode);
/*
* Normal UNIX filesystem behaviour: delete the
* inode when the usage count drops to zero, and
* i_nlink is zero.
*/
int generic_drop_inode(struct inode *inode)
{
return !inode->i_nlink || inode_unhashed(inode);
}
EXPORT_SYMBOL_GPL(generic_drop_inode);
/* /*
* Called when we're dropping the last reference * Called when we're dropping the last reference
* to an inode. * to an inode.
@ -1510,9 +1489,10 @@ static int relatime_need_update(struct vfsmount *mnt, struct inode *inode,
* This function automatically handles read only file systems and media, * This function automatically handles read only file systems and media,
* as well as the "noatime" flag and inode specific "noatime" markers. * as well as the "noatime" flag and inode specific "noatime" markers.
*/ */
void touch_atime(struct vfsmount *mnt, struct dentry *dentry) void touch_atime(struct path *path)
{ {
struct inode *inode = dentry->d_inode; struct vfsmount *mnt = path->mnt;
struct inode *inode = path->dentry->d_inode;
struct timespec now; struct timespec now;
if (inode->i_flags & S_NOATIME) if (inode->i_flags & S_NOATIME)

View File

@ -947,9 +947,8 @@ root_found:
s->s_d_op = &isofs_dentry_ops[table]; s->s_d_op = &isofs_dentry_ops[table];
/* get the root dentry */ /* get the root dentry */
s->s_root = d_alloc_root(inode); s->s_root = d_make_root(inode);
if (!(s->s_root)) { if (!(s->s_root)) {
iput(inode);
error = -ENOMEM; error = -ENOMEM;
goto out_no_inode; goto out_no_inode;
} }

View File

@ -561,9 +561,9 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent)
ret = -ENOMEM; ret = -ENOMEM;
D1(printk(KERN_DEBUG "jffs2_do_fill_super(): d_alloc_root()\n")); D1(printk(KERN_DEBUG "jffs2_do_fill_super(): d_alloc_root()\n"));
sb->s_root = d_alloc_root(root_i); sb->s_root = d_make_root(root_i);
if (!sb->s_root) if (!sb->s_root)
goto out_root_i; goto out_root;
sb->s_maxbytes = 0xFFFFFFFF; sb->s_maxbytes = 0xFFFFFFFF;
sb->s_blocksize = PAGE_CACHE_SIZE; sb->s_blocksize = PAGE_CACHE_SIZE;
@ -573,8 +573,6 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent)
jffs2_start_garbage_collect_thread(c); jffs2_start_garbage_collect_thread(c);
return 0; return 0;
out_root_i:
iput(root_i);
out_root: out_root:
jffs2_free_ino_caches(c); jffs2_free_ino_caches(c);
jffs2_free_raw_node_refs(c); jffs2_free_raw_node_refs(c);

View File

@ -220,12 +220,6 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, umode_t mode)
dquot_initialize(dip); dquot_initialize(dip);
/* link count overflow on parent directory ? */
if (dip->i_nlink == JFS_LINK_MAX) {
rc = -EMLINK;
goto out1;
}
/* /*
* search parent directory for entry/freespace * search parent directory for entry/freespace
* (dtSearch() returns parent directory page pinned) * (dtSearch() returns parent directory page pinned)
@ -806,9 +800,6 @@ static int jfs_link(struct dentry *old_dentry,
jfs_info("jfs_link: %s %s", old_dentry->d_name.name, jfs_info("jfs_link: %s %s", old_dentry->d_name.name,
dentry->d_name.name); dentry->d_name.name);
if (ip->i_nlink == JFS_LINK_MAX)
return -EMLINK;
dquot_initialize(dir); dquot_initialize(dir);
tid = txBegin(ip->i_sb, 0); tid = txBegin(ip->i_sb, 0);
@ -1138,10 +1129,6 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
rc = -ENOTEMPTY; rc = -ENOTEMPTY;
goto out3; goto out3;
} }
} else if ((new_dir != old_dir) &&
(new_dir->i_nlink == JFS_LINK_MAX)) {
rc = -EMLINK;
goto out3;
} }
} else if (new_ip) { } else if (new_ip) {
IWRITE_LOCK(new_ip, RDWRLOCK_NORMAL); IWRITE_LOCK(new_ip, RDWRLOCK_NORMAL);

View File

@ -441,6 +441,7 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent)
return -ENOMEM; return -ENOMEM;
sb->s_fs_info = sbi; sb->s_fs_info = sbi;
sb->s_max_links = JFS_LINK_MAX;
sbi->sb = sb; sbi->sb = sb;
sbi->uid = sbi->gid = sbi->umask = -1; sbi->uid = sbi->gid = sbi->umask = -1;
@ -521,7 +522,7 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent)
ret = PTR_ERR(inode); ret = PTR_ERR(inode);
goto out_no_rw; goto out_no_rw;
} }
sb->s_root = d_alloc_root(inode); sb->s_root = d_make_root(inode);
if (!sb->s_root) if (!sb->s_root)
goto out_no_root; goto out_no_root;
@ -539,7 +540,6 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent)
out_no_root: out_no_root:
jfs_err("jfs_read_super: get root dentry failed"); jfs_err("jfs_read_super: get root dentry failed");
iput(inode);
out_no_rw: out_no_rw:
rc = jfs_umount(sb); rc = jfs_umount(sb);
@ -860,8 +860,14 @@ static int __init init_jfs_fs(void)
jfs_proc_init(); jfs_proc_init();
#endif #endif
return register_filesystem(&jfs_fs_type); rc = register_filesystem(&jfs_fs_type);
if (!rc)
return 0;
#ifdef PROC_FS_JFS
jfs_proc_clean();
#endif
kthread_stop(jfsSyncThread);
kill_committask: kill_committask:
for (i = 0; i < commit_threads; i++) for (i = 0; i < commit_threads; i++)
kthread_stop(jfsCommitThread[i]); kthread_stop(jfsCommitThread[i]);

View File

@ -491,11 +491,9 @@ int simple_fill_super(struct super_block *s, unsigned long magic,
inode->i_op = &simple_dir_inode_operations; inode->i_op = &simple_dir_inode_operations;
inode->i_fop = &simple_dir_operations; inode->i_fop = &simple_dir_operations;
set_nlink(inode, 2); set_nlink(inode, 2);
root = d_alloc_root(inode); root = d_make_root(inode);
if (!root) { if (!root)
iput(inode);
return -ENOMEM; return -ENOMEM;
}
for (i = 0; !files->name || files->name[0]; i++, files++) { for (i = 0; !files->name || files->name[0]; i++, files++) {
if (!files->name) if (!files->name)
continue; continue;
@ -536,7 +534,7 @@ int simple_pin_fs(struct file_system_type *type, struct vfsmount **mount, int *c
spin_lock(&pin_fs_lock); spin_lock(&pin_fs_lock);
if (unlikely(!*mount)) { if (unlikely(!*mount)) {
spin_unlock(&pin_fs_lock); spin_unlock(&pin_fs_lock);
mnt = vfs_kern_mount(type, 0, type->name, NULL); mnt = vfs_kern_mount(type, MS_KERNMOUNT, type->name, NULL);
if (IS_ERR(mnt)) if (IS_ERR(mnt))
return PTR_ERR(mnt); return PTR_ERR(mnt);
spin_lock(&pin_fs_lock); spin_lock(&pin_fs_lock);

View File

@ -558,9 +558,6 @@ static int logfs_link(struct dentry *old_dentry, struct inode *dir,
{ {
struct inode *inode = old_dentry->d_inode; struct inode *inode = old_dentry->d_inode;
if (inode->i_nlink >= LOGFS_LINK_MAX)
return -EMLINK;
inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
ihold(inode); ihold(inode);
inc_nlink(inode); inc_nlink(inode);

View File

@ -315,11 +315,9 @@ static int logfs_get_sb_final(struct super_block *sb)
if (IS_ERR(rootdir)) if (IS_ERR(rootdir))
goto fail; goto fail;
sb->s_root = d_alloc_root(rootdir); sb->s_root = d_make_root(rootdir);
if (!sb->s_root) { if (!sb->s_root)
iput(rootdir);
goto fail; goto fail;
}
/* at that point we know that ->put_super() will be called */ /* at that point we know that ->put_super() will be called */
super->s_erase_page = alloc_pages(GFP_KERNEL, 0); super->s_erase_page = alloc_pages(GFP_KERNEL, 0);
@ -542,6 +540,7 @@ static struct dentry *logfs_get_sb_device(struct logfs_super *super,
* the filesystem incompatible with 32bit systems. * the filesystem incompatible with 32bit systems.
*/ */
sb->s_maxbytes = (1ull << 43) - 1; sb->s_maxbytes = (1ull << 43) - 1;
sb->s_max_links = LOGFS_LINK_MAX;
sb->s_op = &logfs_super_operations; sb->s_op = &logfs_super_operations;
sb->s_flags = flags | MS_NOATIME; sb->s_flags = flags | MS_NOATIME;
@ -627,7 +626,10 @@ static int __init logfs_init(void)
if (ret) if (ret)
goto out2; goto out2;
return register_filesystem(&logfs_fs_type); ret = register_filesystem(&logfs_fs_type);
if (!ret)
return 0;
logfs_destroy_inode_cache();
out2: out2:
logfs_compr_exit(); logfs_compr_exit();
out1: out1:

View File

@ -190,24 +190,24 @@ static int minix_fill_super(struct super_block *s, void *data, int silent)
sbi->s_version = MINIX_V1; sbi->s_version = MINIX_V1;
sbi->s_dirsize = 16; sbi->s_dirsize = 16;
sbi->s_namelen = 14; sbi->s_namelen = 14;
sbi->s_link_max = MINIX_LINK_MAX; s->s_max_links = MINIX_LINK_MAX;
} else if (s->s_magic == MINIX_SUPER_MAGIC2) { } else if (s->s_magic == MINIX_SUPER_MAGIC2) {
sbi->s_version = MINIX_V1; sbi->s_version = MINIX_V1;
sbi->s_dirsize = 32; sbi->s_dirsize = 32;
sbi->s_namelen = 30; sbi->s_namelen = 30;
sbi->s_link_max = MINIX_LINK_MAX; s->s_max_links = MINIX_LINK_MAX;
} else if (s->s_magic == MINIX2_SUPER_MAGIC) { } else if (s->s_magic == MINIX2_SUPER_MAGIC) {
sbi->s_version = MINIX_V2; sbi->s_version = MINIX_V2;
sbi->s_nzones = ms->s_zones; sbi->s_nzones = ms->s_zones;
sbi->s_dirsize = 16; sbi->s_dirsize = 16;
sbi->s_namelen = 14; sbi->s_namelen = 14;
sbi->s_link_max = MINIX2_LINK_MAX; s->s_max_links = MINIX2_LINK_MAX;
} else if (s->s_magic == MINIX2_SUPER_MAGIC2) { } else if (s->s_magic == MINIX2_SUPER_MAGIC2) {
sbi->s_version = MINIX_V2; sbi->s_version = MINIX_V2;
sbi->s_nzones = ms->s_zones; sbi->s_nzones = ms->s_zones;
sbi->s_dirsize = 32; sbi->s_dirsize = 32;
sbi->s_namelen = 30; sbi->s_namelen = 30;
sbi->s_link_max = MINIX2_LINK_MAX; s->s_max_links = MINIX2_LINK_MAX;
} else if ( *(__u16 *)(bh->b_data + 24) == MINIX3_SUPER_MAGIC) { } else if ( *(__u16 *)(bh->b_data + 24) == MINIX3_SUPER_MAGIC) {
m3s = (struct minix3_super_block *) bh->b_data; m3s = (struct minix3_super_block *) bh->b_data;
s->s_magic = m3s->s_magic; s->s_magic = m3s->s_magic;
@ -221,9 +221,9 @@ static int minix_fill_super(struct super_block *s, void *data, int silent)
sbi->s_dirsize = 64; sbi->s_dirsize = 64;
sbi->s_namelen = 60; sbi->s_namelen = 60;
sbi->s_version = MINIX_V3; sbi->s_version = MINIX_V3;
sbi->s_link_max = MINIX2_LINK_MAX;
sbi->s_mount_state = MINIX_VALID_FS; sbi->s_mount_state = MINIX_VALID_FS;
sb_set_blocksize(s, m3s->s_blocksize); sb_set_blocksize(s, m3s->s_blocksize);
s->s_max_links = MINIX2_LINK_MAX;
} else } else
goto out_no_fs; goto out_no_fs;
@ -254,14 +254,6 @@ static int minix_fill_super(struct super_block *s, void *data, int silent)
minix_set_bit(0,sbi->s_imap[0]->b_data); minix_set_bit(0,sbi->s_imap[0]->b_data);
minix_set_bit(0,sbi->s_zmap[0]->b_data); minix_set_bit(0,sbi->s_zmap[0]->b_data);
/* set up enough so that it can read an inode */
s->s_op = &minix_sops;
root_inode = minix_iget(s, MINIX_ROOT_INO);
if (IS_ERR(root_inode)) {
ret = PTR_ERR(root_inode);
goto out_no_root;
}
/* Apparently minix can create filesystems that allocate more blocks for /* Apparently minix can create filesystems that allocate more blocks for
* the bitmaps than needed. We simply ignore that, but verify it didn't * the bitmaps than needed. We simply ignore that, but verify it didn't
* create one with not enough blocks and bail out if so. * create one with not enough blocks and bail out if so.
@ -270,7 +262,7 @@ static int minix_fill_super(struct super_block *s, void *data, int silent)
if (sbi->s_imap_blocks < block) { if (sbi->s_imap_blocks < block) {
printk("MINIX-fs: file system does not have enough " printk("MINIX-fs: file system does not have enough "
"imap blocks allocated. Refusing to mount\n"); "imap blocks allocated. Refusing to mount\n");
goto out_iput; goto out_no_bitmap;
} }
block = minix_blocks_needed( block = minix_blocks_needed(
@ -279,13 +271,21 @@ static int minix_fill_super(struct super_block *s, void *data, int silent)
if (sbi->s_zmap_blocks < block) { if (sbi->s_zmap_blocks < block) {
printk("MINIX-fs: file system does not have enough " printk("MINIX-fs: file system does not have enough "
"zmap blocks allocated. Refusing to mount.\n"); "zmap blocks allocated. Refusing to mount.\n");
goto out_iput; goto out_no_bitmap;
}
/* set up enough so that it can read an inode */
s->s_op = &minix_sops;
root_inode = minix_iget(s, MINIX_ROOT_INO);
if (IS_ERR(root_inode)) {
ret = PTR_ERR(root_inode);
goto out_no_root;
} }
ret = -ENOMEM; ret = -ENOMEM;
s->s_root = d_alloc_root(root_inode); s->s_root = d_make_root(root_inode);
if (!s->s_root) if (!s->s_root)
goto out_iput; goto out_no_root;
if (!(s->s_flags & MS_RDONLY)) { if (!(s->s_flags & MS_RDONLY)) {
if (sbi->s_version != MINIX_V3) /* s_state is now out from V3 sb */ if (sbi->s_version != MINIX_V3) /* s_state is now out from V3 sb */
@ -301,10 +301,6 @@ static int minix_fill_super(struct super_block *s, void *data, int silent)
return 0; return 0;
out_iput:
iput(root_inode);
goto out_freemap;
out_no_root: out_no_root:
if (!silent) if (!silent)
printk("MINIX-fs: get root inode failed\n"); printk("MINIX-fs: get root inode failed\n");

View File

@ -34,7 +34,6 @@ struct minix_sb_info {
unsigned long s_max_size; unsigned long s_max_size;
int s_dirsize; int s_dirsize;
int s_namelen; int s_namelen;
int s_link_max;
struct buffer_head ** s_imap; struct buffer_head ** s_imap;
struct buffer_head ** s_zmap; struct buffer_head ** s_zmap;
struct buffer_head * s_sbh; struct buffer_head * s_sbh;

View File

@ -94,9 +94,6 @@ static int minix_link(struct dentry * old_dentry, struct inode * dir,
{ {
struct inode *inode = old_dentry->d_inode; struct inode *inode = old_dentry->d_inode;
if (inode->i_nlink >= minix_sb(inode->i_sb)->s_link_max)
return -EMLINK;
inode->i_ctime = CURRENT_TIME_SEC; inode->i_ctime = CURRENT_TIME_SEC;
inode_inc_link_count(inode); inode_inc_link_count(inode);
ihold(inode); ihold(inode);
@ -106,10 +103,7 @@ static int minix_link(struct dentry * old_dentry, struct inode * dir,
static int minix_mkdir(struct inode * dir, struct dentry *dentry, umode_t mode) static int minix_mkdir(struct inode * dir, struct dentry *dentry, umode_t mode)
{ {
struct inode * inode; struct inode * inode;
int err = -EMLINK; int err;
if (dir->i_nlink >= minix_sb(dir->i_sb)->s_link_max)
goto out;
inode_inc_link_count(dir); inode_inc_link_count(dir);
@ -181,7 +175,6 @@ static int minix_rmdir(struct inode * dir, struct dentry *dentry)
static int minix_rename(struct inode * old_dir, struct dentry *old_dentry, static int minix_rename(struct inode * old_dir, struct dentry *old_dentry,
struct inode * new_dir, struct dentry *new_dentry) struct inode * new_dir, struct dentry *new_dentry)
{ {
struct minix_sb_info * info = minix_sb(old_dir->i_sb);
struct inode * old_inode = old_dentry->d_inode; struct inode * old_inode = old_dentry->d_inode;
struct inode * new_inode = new_dentry->d_inode; struct inode * new_inode = new_dentry->d_inode;
struct page * dir_page = NULL; struct page * dir_page = NULL;
@ -219,11 +212,6 @@ static int minix_rename(struct inode * old_dir, struct dentry *old_dentry,
drop_nlink(new_inode); drop_nlink(new_inode);
inode_dec_link_count(new_inode); inode_dec_link_count(new_inode);
} else { } else {
if (dir_de) {
err = -EMLINK;
if (new_dir->i_nlink >= info->s_link_max)
goto out_dir;
}
err = minix_add_link(new_dentry, old_inode); err = minix_add_link(new_dentry, old_inode);
if (err) if (err)
goto out_dir; goto out_dir;

View File

@ -642,7 +642,7 @@ follow_link(struct path *link, struct nameidata *nd, void **p)
cond_resched(); cond_resched();
current->total_link_count++; current->total_link_count++;
touch_atime(link->mnt, dentry); touch_atime(link);
nd_set_link(nd, NULL); nd_set_link(nd, NULL);
error = security_inode_follow_link(link->dentry, nd); error = security_inode_follow_link(link->dentry, nd);
@ -2691,6 +2691,7 @@ SYSCALL_DEFINE3(mknod, const char __user *, filename, umode_t, mode, unsigned, d
int vfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) int vfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
{ {
int error = may_create(dir, dentry); int error = may_create(dir, dentry);
unsigned max_links = dir->i_sb->s_max_links;
if (error) if (error)
return error; return error;
@ -2703,6 +2704,9 @@ int vfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
if (error) if (error)
return error; return error;
if (max_links && dir->i_nlink >= max_links)
return -EMLINK;
error = dir->i_op->mkdir(dir, dentry, mode); error = dir->i_op->mkdir(dir, dentry, mode);
if (!error) if (!error)
fsnotify_mkdir(dir, dentry); fsnotify_mkdir(dir, dentry);
@ -3033,6 +3037,7 @@ SYSCALL_DEFINE2(symlink, const char __user *, oldname, const char __user *, newn
int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry) int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry)
{ {
struct inode *inode = old_dentry->d_inode; struct inode *inode = old_dentry->d_inode;
unsigned max_links = dir->i_sb->s_max_links;
int error; int error;
if (!inode) if (!inode)
@ -3063,6 +3068,8 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de
/* Make sure we don't allow creating hardlink to an unlinked file */ /* Make sure we don't allow creating hardlink to an unlinked file */
if (inode->i_nlink == 0) if (inode->i_nlink == 0)
error = -ENOENT; error = -ENOENT;
else if (max_links && inode->i_nlink >= max_links)
error = -EMLINK;
else else
error = dir->i_op->link(old_dentry, dir, new_dentry); error = dir->i_op->link(old_dentry, dir, new_dentry);
mutex_unlock(&inode->i_mutex); mutex_unlock(&inode->i_mutex);
@ -3172,6 +3179,7 @@ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
{ {
int error = 0; int error = 0;
struct inode *target = new_dentry->d_inode; struct inode *target = new_dentry->d_inode;
unsigned max_links = new_dir->i_sb->s_max_links;
/* /*
* If we are going to change the parent - check write permissions, * If we are going to change the parent - check write permissions,
@ -3195,6 +3203,11 @@ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
if (d_mountpoint(old_dentry) || d_mountpoint(new_dentry)) if (d_mountpoint(old_dentry) || d_mountpoint(new_dentry))
goto out; goto out;
error = -EMLINK;
if (max_links && !target && new_dir != old_dir &&
new_dir->i_nlink >= max_links)
goto out;
if (target) if (target)
shrink_dcache_parent(new_dentry); shrink_dcache_parent(new_dentry);
error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);

View File

@ -716,13 +716,11 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
if (!root_inode) if (!root_inode)
goto out_disconnect; goto out_disconnect;
DPRINTK("ncp_fill_super: root vol=%d\n", NCP_FINFO(root_inode)->volNumber); DPRINTK("ncp_fill_super: root vol=%d\n", NCP_FINFO(root_inode)->volNumber);
sb->s_root = d_alloc_root(root_inode); sb->s_root = d_make_root(root_inode);
if (!sb->s_root) if (!sb->s_root)
goto out_no_root; goto out_disconnect;
return 0; return 0;
out_no_root:
iput(root_inode);
out_disconnect: out_disconnect:
ncp_lock_server(server); ncp_lock_server(server);
ncp_disconnect(server); ncp_disconnect(server);

View File

@ -49,11 +49,9 @@ static int nfs_superblock_set_dummy_root(struct super_block *sb, struct inode *i
{ {
/* The mntroot acts as the dummy root dentry for this superblock */ /* The mntroot acts as the dummy root dentry for this superblock */
if (sb->s_root == NULL) { if (sb->s_root == NULL) {
sb->s_root = d_alloc_root(inode); sb->s_root = d_make_root(inode);
if (sb->s_root == NULL) { if (sb->s_root == NULL)
iput(inode);
return -ENOMEM; return -ENOMEM;
}
ihold(inode); ihold(inode);
/* /*
* Ensure that this dentry is invisible to d_find_alias(). * Ensure that this dentry is invisible to d_find_alias().

View File

@ -72,7 +72,7 @@ int nfsd_fault_inject_init(void)
{ {
unsigned int i; unsigned int i;
struct nfsd_fault_inject_op *op; struct nfsd_fault_inject_op *op;
mode_t mode = S_IFREG | S_IRUSR | S_IWUSR; umode_t mode = S_IFREG | S_IRUSR | S_IWUSR;
debug_dir = debugfs_create_dir("nfsd", NULL); debug_dir = debugfs_create_dir("nfsd", NULL);
if (!debug_dir) if (!debug_dir)

View File

@ -1541,30 +1541,31 @@ do_nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
__be32 __be32
nfsd_readlink(struct svc_rqst *rqstp, struct svc_fh *fhp, char *buf, int *lenp) nfsd_readlink(struct svc_rqst *rqstp, struct svc_fh *fhp, char *buf, int *lenp)
{ {
struct dentry *dentry;
struct inode *inode; struct inode *inode;
mm_segment_t oldfs; mm_segment_t oldfs;
__be32 err; __be32 err;
int host_err; int host_err;
struct path path;
err = fh_verify(rqstp, fhp, S_IFLNK, NFSD_MAY_NOP); err = fh_verify(rqstp, fhp, S_IFLNK, NFSD_MAY_NOP);
if (err) if (err)
goto out; goto out;
dentry = fhp->fh_dentry; path.mnt = fhp->fh_export->ex_path.mnt;
inode = dentry->d_inode; path.dentry = fhp->fh_dentry;
inode = path.dentry->d_inode;
err = nfserr_inval; err = nfserr_inval;
if (!inode->i_op->readlink) if (!inode->i_op->readlink)
goto out; goto out;
touch_atime(fhp->fh_export->ex_path.mnt, dentry); touch_atime(&path);
/* N.B. Why does this call need a get_fs()?? /* N.B. Why does this call need a get_fs()??
* Remove the set_fs and watch the fireworks:-) --okir * Remove the set_fs and watch the fireworks:-) --okir
*/ */
oldfs = get_fs(); set_fs(KERNEL_DS); oldfs = get_fs(); set_fs(KERNEL_DS);
host_err = inode->i_op->readlink(dentry, buf, *lenp); host_err = inode->i_op->readlink(path.dentry, buf, *lenp);
set_fs(oldfs); set_fs(oldfs);
if (host_err < 0) if (host_err < 0)

View File

@ -193,9 +193,6 @@ static int nilfs_link(struct dentry *old_dentry, struct inode *dir,
struct nilfs_transaction_info ti; struct nilfs_transaction_info ti;
int err; int err;
if (inode->i_nlink >= NILFS_LINK_MAX)
return -EMLINK;
err = nilfs_transaction_begin(dir->i_sb, &ti, 1); err = nilfs_transaction_begin(dir->i_sb, &ti, 1);
if (err) if (err)
return err; return err;
@ -219,9 +216,6 @@ static int nilfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
struct nilfs_transaction_info ti; struct nilfs_transaction_info ti;
int err; int err;
if (dir->i_nlink >= NILFS_LINK_MAX)
return -EMLINK;
err = nilfs_transaction_begin(dir->i_sb, &ti, 1); err = nilfs_transaction_begin(dir->i_sb, &ti, 1);
if (err) if (err)
return err; return err;
@ -400,11 +394,6 @@ static int nilfs_rename(struct inode *old_dir, struct dentry *old_dentry,
drop_nlink(new_inode); drop_nlink(new_inode);
nilfs_mark_inode_dirty(new_inode); nilfs_mark_inode_dirty(new_inode);
} else { } else {
if (dir_de) {
err = -EMLINK;
if (new_dir->i_nlink >= NILFS_LINK_MAX)
goto out_dir;
}
err = nilfs_add_link(new_dentry, old_inode); err = nilfs_add_link(new_dentry, old_inode);
if (err) if (err)
goto out_dir; goto out_dir;

View File

@ -917,9 +917,8 @@ static int nilfs_get_root_dentry(struct super_block *sb,
if (root->cno == NILFS_CPTREE_CURRENT_CNO) { if (root->cno == NILFS_CPTREE_CURRENT_CNO) {
dentry = d_find_alias(inode); dentry = d_find_alias(inode);
if (!dentry) { if (!dentry) {
dentry = d_alloc_root(inode); dentry = d_make_root(inode);
if (!dentry) { if (!dentry) {
iput(inode);
ret = -ENOMEM; ret = -ENOMEM;
goto failed_dentry; goto failed_dentry;
} }
@ -1059,6 +1058,7 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent)
sb->s_export_op = &nilfs_export_ops; sb->s_export_op = &nilfs_export_ops;
sb->s_root = NULL; sb->s_root = NULL;
sb->s_time_gran = 1; sb->s_time_gran = 1;
sb->s_max_links = NILFS_LINK_MAX;
bdi = sb->s_bdev->bd_inode->i_mapping->backing_dev_info; bdi = sb->s_bdev->bd_inode->i_mapping->backing_dev_info;
sb->s_bdi = bdi ? : &default_backing_dev_info; sb->s_bdi = bdi ? : &default_backing_dev_info;

View File

@ -2908,9 +2908,10 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent)
ntfs_error(sb, "Failed to load system files."); ntfs_error(sb, "Failed to load system files.");
goto unl_upcase_iput_tmp_ino_err_out_now; goto unl_upcase_iput_tmp_ino_err_out_now;
} }
if ((sb->s_root = d_alloc_root(vol->root_ino))) {
/* We grab a reference, simulating an ntfs_iget(). */ /* We grab a reference, simulating an ntfs_iget(). */
ihold(vol->root_ino); ihold(vol->root_ino);
if ((sb->s_root = d_make_root(vol->root_ino))) {
ntfs_debug("Exiting, status successful."); ntfs_debug("Exiting, status successful.");
/* Release the default upcase if it has no users. */ /* Release the default upcase if it has no users. */
mutex_lock(&ntfs_lock); mutex_lock(&ntfs_lock);
@ -3158,6 +3159,8 @@ static int __init init_ntfs_fs(void)
} }
printk(KERN_CRIT "NTFS: Failed to register NTFS filesystem driver!\n"); printk(KERN_CRIT "NTFS: Failed to register NTFS filesystem driver!\n");
/* Unregister the ntfs sysctls. */
ntfs_sysctl(0);
sysctl_err_out: sysctl_err_out:
kmem_cache_destroy(ntfs_big_inode_cache); kmem_cache_destroy(ntfs_big_inode_cache);
big_inode_err_out: big_inode_err_out:

Some files were not shown because too many files have changed in this diff Show More