diff --git a/[refs] b/[refs] index 01fea24a340a..822b7b501e83 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 3ae5080f4c2e293229508dabe7c8a90af4e4c460 +refs/heads/master: 568d9a8f6d4bf81e0672c74573dc02981d31e3ea diff --git a/trunk/arch/alpha/kernel/entry.S b/trunk/arch/alpha/kernel/entry.S index b45d913a51c3..e4a54b615894 100644 --- a/trunk/arch/alpha/kernel/entry.S +++ b/trunk/arch/alpha/kernel/entry.S @@ -903,9 +903,8 @@ sys_alpha_pipe: stq $26, 0($sp) .prologue 0 - mov $31, $17 lda $16, 8($sp) - jsr $26, do_pipe_flags + jsr $26, do_pipe ldq $26, 0($sp) bne $0, 1f diff --git a/trunk/arch/alpha/kernel/osf_sys.c b/trunk/arch/alpha/kernel/osf_sys.c index 42ee05981e71..ae41f097864b 100644 --- a/trunk/arch/alpha/kernel/osf_sys.c +++ b/trunk/arch/alpha/kernel/osf_sys.c @@ -46,6 +46,8 @@ #include #include +extern int do_pipe(int *); + /* * Brk needs to return an error. Still support Linux's brk(0) query idiom, * which OSF programs just shouldn't be doing. We're still not quite diff --git a/trunk/arch/ia64/ia32/ia32_entry.S b/trunk/arch/ia64/ia32/ia32_entry.S index af9405cd70e5..a46f8395e9a5 100644 --- a/trunk/arch/ia64/ia32/ia32_entry.S +++ b/trunk/arch/ia64/ia32/ia32_entry.S @@ -240,7 +240,7 @@ ia32_syscall_table: data8 sys_ni_syscall data8 sys_umask /* 60 */ data8 sys_chroot - data8 compat_sys_ustat + data8 sys_ustat data8 sys_dup2 data8 sys_getppid data8 sys_getpgrp /* 65 */ diff --git a/trunk/arch/ia64/kernel/perfmon.c b/trunk/arch/ia64/kernel/perfmon.c index 5c0f408cfd71..0e499757309b 100644 --- a/trunk/arch/ia64/kernel/perfmon.c +++ b/trunk/arch/ia64/kernel/perfmon.c @@ -2196,7 +2196,7 @@ pfmfs_delete_dentry(struct dentry *dentry) return 1; } -static const struct dentry_operations pfmfs_dentry_operations = { +static struct dentry_operations pfmfs_dentry_operations = { .d_delete = pfmfs_delete_dentry, }; diff --git a/trunk/arch/mips/kernel/linux32.c b/trunk/arch/mips/kernel/linux32.c index 2a472713de8e..49aac6e17df9 100644 --- a/trunk/arch/mips/kernel/linux32.c +++ b/trunk/arch/mips/kernel/linux32.c @@ -355,6 +355,40 @@ SYSCALL_DEFINE1(32_personality, unsigned long, personality) return ret; } +/* ustat compatibility */ +struct ustat32 { + compat_daddr_t f_tfree; + compat_ino_t f_tinode; + char f_fname[6]; + char f_fpack[6]; +}; + +extern asmlinkage long sys_ustat(dev_t dev, struct ustat __user * ubuf); + +SYSCALL_DEFINE2(32_ustat, dev_t, dev, struct ustat32 __user *, ubuf32) +{ + int err; + struct ustat tmp; + struct ustat32 tmp32; + mm_segment_t old_fs = get_fs(); + + set_fs(KERNEL_DS); + err = sys_ustat(dev, (struct ustat __user *)&tmp); + set_fs(old_fs); + + if (err) + goto out; + + memset(&tmp32, 0, sizeof(struct ustat32)); + tmp32.f_tfree = tmp.f_tfree; + tmp32.f_tinode = tmp.f_tinode; + + err = copy_to_user(ubuf32, &tmp32, sizeof(struct ustat32)) ? -EFAULT : 0; + +out: + return err; +} + SYSCALL_DEFINE4(32_sendfile, long, out_fd, long, in_fd, compat_off_t __user *, offset, s32, count) { diff --git a/trunk/arch/mips/kernel/scall64-n32.S b/trunk/arch/mips/kernel/scall64-n32.S index f61d6b0e5731..7438e92f8a01 100644 --- a/trunk/arch/mips/kernel/scall64-n32.S +++ b/trunk/arch/mips/kernel/scall64-n32.S @@ -253,7 +253,7 @@ EXPORT(sysn32_call_table) PTR compat_sys_utime /* 6130 */ PTR sys_mknod PTR sys_32_personality - PTR compat_sys_ustat + PTR sys_32_ustat PTR compat_sys_statfs PTR compat_sys_fstatfs /* 6135 */ PTR sys_sysfs diff --git a/trunk/arch/mips/kernel/scall64-o32.S b/trunk/arch/mips/kernel/scall64-o32.S index 60997f1f69d4..b0fef4ff9827 100644 --- a/trunk/arch/mips/kernel/scall64-o32.S +++ b/trunk/arch/mips/kernel/scall64-o32.S @@ -265,7 +265,7 @@ sys_call_table: PTR sys_olduname PTR sys_umask /* 4060 */ PTR sys_chroot - PTR compat_sys_ustat + PTR sys_32_ustat PTR sys_dup2 PTR sys_getppid PTR sys_getpgrp /* 4065 */ diff --git a/trunk/arch/parisc/kernel/syscall_table.S b/trunk/arch/parisc/kernel/syscall_table.S index 03b9a01bc16c..303d2b647e41 100644 --- a/trunk/arch/parisc/kernel/syscall_table.S +++ b/trunk/arch/parisc/kernel/syscall_table.S @@ -130,7 +130,7 @@ ENTRY_OURS(newuname) ENTRY_SAME(umask) /* 60 */ ENTRY_SAME(chroot) - ENTRY_COMP(ustat) + ENTRY_SAME(ustat) ENTRY_SAME(dup2) ENTRY_SAME(getppid) ENTRY_SAME(getpgrp) /* 65 */ diff --git a/trunk/arch/powerpc/include/asm/systbl.h b/trunk/arch/powerpc/include/asm/systbl.h index fe166491e9dc..72353f6070a4 100644 --- a/trunk/arch/powerpc/include/asm/systbl.h +++ b/trunk/arch/powerpc/include/asm/systbl.h @@ -65,7 +65,7 @@ SYSCALL(ni_syscall) SYSX(sys_ni_syscall,sys_olduname, sys_olduname) COMPAT_SYS_SPU(umask) SYSCALL_SPU(chroot) -COMPAT_SYS(ustat) +SYSCALL(ustat) SYSCALL_SPU(dup2) SYSCALL_SPU(getppid) SYSCALL_SPU(getpgrp) diff --git a/trunk/arch/s390/kernel/compat_wrapper.S b/trunk/arch/s390/kernel/compat_wrapper.S index 87cf5a79a351..62c706eb0de6 100644 --- a/trunk/arch/s390/kernel/compat_wrapper.S +++ b/trunk/arch/s390/kernel/compat_wrapper.S @@ -252,7 +252,7 @@ sys32_chroot_wrapper: sys32_ustat_wrapper: llgfr %r2,%r2 # dev_t llgtr %r3,%r3 # struct ustat * - jg compat_sys_ustat + jg sys_ustat .globl sys32_dup2_wrapper sys32_dup2_wrapper: diff --git a/trunk/arch/sparc/kernel/time_64.c b/trunk/arch/sparc/kernel/time_64.c index 4ee2e48c4b39..642562d83ec4 100644 --- a/trunk/arch/sparc/kernel/time_64.c +++ b/trunk/arch/sparc/kernel/time_64.c @@ -724,14 +724,12 @@ void timer_interrupt(int irq, struct pt_regs *regs) unsigned long tick_mask = tick_ops->softint_mask; int cpu = smp_processor_id(); struct clock_event_device *evt = &per_cpu(sparc64_events, cpu); - struct irq_desc *desc; clear_softint(tick_mask); irq_enter(); - desc = irq_to_desc(0); - kstat_incr_irqs_this_cpu(0, desc); + kstat_this_cpu.irqs[0]++; if (unlikely(!evt->event_handler)) { printk(KERN_WARNING diff --git a/trunk/arch/x86/ia32/ia32entry.S b/trunk/arch/x86/ia32/ia32entry.S index 8ef8876666b2..5a0d76dc56a4 100644 --- a/trunk/arch/x86/ia32/ia32entry.S +++ b/trunk/arch/x86/ia32/ia32entry.S @@ -557,7 +557,7 @@ ia32_sys_call_table: .quad sys32_olduname .quad sys_umask /* 60 */ .quad sys_chroot - .quad compat_sys_ustat + .quad sys32_ustat .quad sys_dup2 .quad sys_getppid .quad sys_getpgrp /* 65 */ diff --git a/trunk/arch/x86/ia32/sys_ia32.c b/trunk/arch/x86/ia32/sys_ia32.c index efac92fd1efb..6c0d7f6231af 100644 --- a/trunk/arch/x86/ia32/sys_ia32.c +++ b/trunk/arch/x86/ia32/sys_ia32.c @@ -638,6 +638,28 @@ long sys32_uname(struct old_utsname __user *name) return err ? -EFAULT : 0; } +long sys32_ustat(unsigned dev, struct ustat32 __user *u32p) +{ + struct ustat u; + mm_segment_t seg; + int ret; + + seg = get_fs(); + set_fs(KERNEL_DS); + ret = sys_ustat(dev, (struct ustat __user *)&u); + set_fs(seg); + if (ret < 0) + return ret; + + if (!access_ok(VERIFY_WRITE, u32p, sizeof(struct ustat32)) || + __put_user((__u32) u.f_tfree, &u32p->f_tfree) || + __put_user((__u32) u.f_tinode, &u32p->f_tfree) || + __copy_to_user(&u32p->f_fname, u.f_fname, sizeof(u.f_fname)) || + __copy_to_user(&u32p->f_fpack, u.f_fpack, sizeof(u.f_fpack))) + ret = -EFAULT; + return ret; +} + asmlinkage long sys32_execve(char __user *name, compat_uptr_t __user *argv, compat_uptr_t __user *envp, struct pt_regs *regs) { diff --git a/trunk/arch/x86/include/asm/ia32.h b/trunk/arch/x86/include/asm/ia32.h index 1f7e62517284..50ca486fd88c 100644 --- a/trunk/arch/x86/include/asm/ia32.h +++ b/trunk/arch/x86/include/asm/ia32.h @@ -129,6 +129,13 @@ typedef struct compat_siginfo { } _sifields; } compat_siginfo_t; +struct ustat32 { + __u32 f_tfree; + compat_ino_t f_tinode; + char f_fname[6]; + char f_fpack[6]; +}; + #define IA32_STACK_TOP IA32_PAGE_OFFSET #ifdef __KERNEL__ diff --git a/trunk/arch/x86/include/asm/sys_ia32.h b/trunk/arch/x86/include/asm/sys_ia32.h index 72a6dcd1299b..ffb08be2a530 100644 --- a/trunk/arch/x86/include/asm/sys_ia32.h +++ b/trunk/arch/x86/include/asm/sys_ia32.h @@ -70,6 +70,8 @@ struct old_utsname; asmlinkage long sys32_olduname(struct oldold_utsname __user *); long sys32_uname(struct old_utsname __user *); +long sys32_ustat(unsigned, struct ustat32 __user *); + asmlinkage long sys32_execve(char __user *, compat_uptr_t __user *, compat_uptr_t __user *, struct pt_regs *); asmlinkage long sys32_clone(unsigned int, unsigned int, struct pt_regs *); diff --git a/trunk/drivers/gpu/drm/i915/i915_gem_tiling.c b/trunk/drivers/gpu/drm/i915/i915_gem_tiling.c index 7fb4191ef934..4cce1aef438e 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -96,16 +96,16 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev) */ swizzle_x = I915_BIT_6_SWIZZLE_NONE; swizzle_y = I915_BIT_6_SWIZZLE_NONE; - } else if ((!IS_I965G(dev) && !IS_G33(dev)) || IS_I965GM(dev) || - IS_GM45(dev)) { + } else if (IS_MOBILE(dev)) { uint32_t dcc; - /* On 915-945 and GM965, channel interleave by the CPU is - * determined by DCC. The CPU will alternate based on bit 6 - * in interleaved mode, and the GPU will then also alternate - * on bit 6, 9, and 10 for X, but the CPU may also optionally - * alternate based on bit 17 (XOR not disabled and XOR - * bit == 17). + /* On mobile 9xx chipsets, channel interleave by the CPU is + * determined by DCC. For single-channel, neither the CPU + * nor the GPU do swizzling. For dual channel interleaved, + * the GPU's interleave is bit 9 and 10 for X tiled, and bit + * 9 for Y tiled. The CPU's interleave is independent, and + * can be based on either bit 11 (haven't seen this yet) or + * bit 17 (common). */ dcc = I915_READ(DCC); switch (dcc & DCC_ADDRESSING_MODE_MASK) { @@ -115,19 +115,18 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev) swizzle_y = I915_BIT_6_SWIZZLE_NONE; break; case DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED: - if (IS_I915G(dev) || IS_I915GM(dev) || - dcc & DCC_CHANNEL_XOR_DISABLE) { + if (dcc & DCC_CHANNEL_XOR_DISABLE) { + /* This is the base swizzling by the GPU for + * tiled buffers. + */ swizzle_x = I915_BIT_6_SWIZZLE_9_10; swizzle_y = I915_BIT_6_SWIZZLE_9; - } else if ((IS_I965GM(dev) || IS_GM45(dev)) && - (dcc & DCC_CHANNEL_XOR_BIT_17) == 0) { - /* GM965/GM45 does either bit 11 or bit 17 - * swizzling. - */ + } else if ((dcc & DCC_CHANNEL_XOR_BIT_17) == 0) { + /* Bit 11 swizzling by the CPU in addition. */ swizzle_x = I915_BIT_6_SWIZZLE_9_10_11; swizzle_y = I915_BIT_6_SWIZZLE_9_11; } else { - /* Bit 17 or perhaps other swizzling */ + /* Bit 17 swizzling by the CPU in addition. */ swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN; swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN; } diff --git a/trunk/drivers/infiniband/hw/nes/nes_nic.c b/trunk/drivers/infiniband/hw/nes/nes_nic.c index ecb1f6fd6276..8d3e4c6f237e 100644 --- a/trunk/drivers/infiniband/hw/nes/nes_nic.c +++ b/trunk/drivers/infiniband/hw/nes/nes_nic.c @@ -1602,6 +1602,8 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev, netif_napi_add(netdev, &nesvnic->napi, nes_netdev_poll, 128); nes_debug(NES_DBG_INIT, "Enabling VLAN Insert/Delete.\n"); netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; + netdev->vlan_rx_register = nes_netdev_vlan_rx_register; + netdev->features |= NETIF_F_LLTX; /* Fill in the port structure */ nesvnic->netdev = netdev; diff --git a/trunk/drivers/mtd/mtdsuper.c b/trunk/drivers/mtd/mtdsuper.c index 92285d0089c2..00d46e137b2a 100644 --- a/trunk/drivers/mtd/mtdsuper.c +++ b/trunk/drivers/mtd/mtdsuper.c @@ -81,16 +81,13 @@ static int get_sb_mtd_aux(struct file_system_type *fs_type, int flags, /* go */ sb->s_flags |= MS_ACTIVE; - simple_set_mnt(mnt, sb); - - return 0; + return simple_set_mnt(mnt, sb); /* new mountpoint for an already mounted superblock */ already_mounted: DEBUG(1, "MTDSB: Device %d (\"%s\") is already mounted\n", mtd->index, mtd->name); - simple_set_mnt(mnt, sb); - ret = 0; + ret = simple_set_mnt(mnt, sb); goto out_put; out_error: diff --git a/trunk/fs/9p/v9fs_vfs.h b/trunk/fs/9p/v9fs_vfs.h index f0c7de78e205..c295ba786edd 100644 --- a/trunk/fs/9p/v9fs_vfs.h +++ b/trunk/fs/9p/v9fs_vfs.h @@ -41,8 +41,8 @@ extern struct file_system_type v9fs_fs_type; extern const struct address_space_operations v9fs_addr_operations; extern const struct file_operations v9fs_file_operations; extern const struct file_operations v9fs_dir_operations; -extern const struct dentry_operations v9fs_dentry_operations; -extern const struct dentry_operations v9fs_cached_dentry_operations; +extern struct dentry_operations v9fs_dentry_operations; +extern struct dentry_operations v9fs_cached_dentry_operations; struct inode *v9fs_get_inode(struct super_block *sb, int mode); ino_t v9fs_qid2ino(struct p9_qid *qid); diff --git a/trunk/fs/9p/vfs_dentry.c b/trunk/fs/9p/vfs_dentry.c index d74325295b1e..06dcc7c4f234 100644 --- a/trunk/fs/9p/vfs_dentry.c +++ b/trunk/fs/9p/vfs_dentry.c @@ -104,12 +104,12 @@ void v9fs_dentry_release(struct dentry *dentry) } } -const struct dentry_operations v9fs_cached_dentry_operations = { +struct dentry_operations v9fs_cached_dentry_operations = { .d_delete = v9fs_cached_dentry_delete, .d_release = v9fs_dentry_release, }; -const struct dentry_operations v9fs_dentry_operations = { +struct dentry_operations v9fs_dentry_operations = { .d_delete = v9fs_dentry_delete, .d_release = v9fs_dentry_release, }; diff --git a/trunk/fs/9p/vfs_super.c b/trunk/fs/9p/vfs_super.c index 5f8ab8adb5f5..93212e40221a 100644 --- a/trunk/fs/9p/vfs_super.c +++ b/trunk/fs/9p/vfs_super.c @@ -168,9 +168,8 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags, p9stat_free(st); kfree(st); -P9_DPRINTK(P9_DEBUG_VFS, " simple set mount, return 0\n"); - simple_set_mnt(mnt, sb); - return 0; +P9_DPRINTK(P9_DEBUG_VFS, " return simple set mount\n"); + return simple_set_mnt(mnt, sb); release_sb: if (sb) { diff --git a/trunk/fs/Kconfig b/trunk/fs/Kconfig index cef8b18ceaa3..93945dd0b1ae 100644 --- a/trunk/fs/Kconfig +++ b/trunk/fs/Kconfig @@ -56,7 +56,61 @@ endif # BLOCK source "fs/notify/Kconfig" -source "fs/quota/Kconfig" +config QUOTA + bool "Quota support" + help + If you say Y here, you will be able to set per user limits for disk + usage (also called disk quotas). Currently, it works for the + ext2, ext3, and reiserfs file system. ext3 also supports journalled + quotas for which you don't need to run quotacheck(8) after an unclean + shutdown. + For further details, read the Quota mini-HOWTO, available from + , or the documentation provided + with the quota tools. Probably the quota support is only useful for + multi user systems. If unsure, say N. + +config QUOTA_NETLINK_INTERFACE + bool "Report quota messages through netlink interface" + depends on QUOTA && NET + help + If you say Y here, quota warnings (about exceeding softlimit, reaching + hardlimit, etc.) will be reported through netlink interface. If unsure, + say Y. + +config PRINT_QUOTA_WARNING + bool "Print quota warnings to console (OBSOLETE)" + depends on QUOTA + default y + help + If you say Y here, quota warnings (about exceeding softlimit, reaching + hardlimit, etc.) will be printed to the process' controlling terminal. + Note that this behavior is currently deprecated and may go away in + future. Please use notification via netlink socket instead. + +# Generic support for tree structured quota files. Seleted when needed. +config QUOTA_TREE + tristate + +config QFMT_V1 + tristate "Old quota format support" + depends on QUOTA + help + This quota format was (is) used by kernels earlier than 2.4.22. If + you have quota working and you don't want to convert to new quota + format say Y here. + +config QFMT_V2 + tristate "Quota format v2 support" + depends on QUOTA + select QUOTA_TREE + help + This quota format allows using quotas with 32-bit UIDs/GIDs. If you + need this functionality say Y here. + +config QUOTACTL + bool + depends on XFS_QUOTA || QUOTA + default y source "fs/autofs/Kconfig" source "fs/autofs4/Kconfig" diff --git a/trunk/fs/Makefile b/trunk/fs/Makefile index 6e82a307bcd4..dc20db348679 100644 --- a/trunk/fs/Makefile +++ b/trunk/fs/Makefile @@ -51,7 +51,11 @@ obj-$(CONFIG_FS_POSIX_ACL) += posix_acl.o xattr_acl.o obj-$(CONFIG_NFS_COMMON) += nfs_common/ obj-$(CONFIG_GENERIC_ACL) += generic_acl.o -obj-y += quota/ +obj-$(CONFIG_QUOTA) += dquot.o +obj-$(CONFIG_QFMT_V1) += quota_v1.o +obj-$(CONFIG_QFMT_V2) += quota_v2.o +obj-$(CONFIG_QUOTA_TREE) += quota_tree.o +obj-$(CONFIG_QUOTACTL) += quota.o obj-$(CONFIG_PROC_FS) += proc/ obj-y += partitions/ diff --git a/trunk/fs/adfs/adfs.h b/trunk/fs/adfs/adfs.h index e0a85dbeeb88..831157502d5a 100644 --- a/trunk/fs/adfs/adfs.h +++ b/trunk/fs/adfs/adfs.h @@ -86,7 +86,7 @@ void __adfs_error(struct super_block *sb, const char *function, /* dir_*.c */ extern const struct inode_operations adfs_dir_inode_operations; extern const struct file_operations adfs_dir_operations; -extern const struct dentry_operations adfs_dentry_operations; +extern struct dentry_operations adfs_dentry_operations; extern struct adfs_dir_ops adfs_f_dir_ops; extern struct adfs_dir_ops adfs_fplus_dir_ops; diff --git a/trunk/fs/adfs/dir.c b/trunk/fs/adfs/dir.c index e867ccf37246..85a30e929800 100644 --- a/trunk/fs/adfs/dir.c +++ b/trunk/fs/adfs/dir.c @@ -263,7 +263,7 @@ adfs_compare(struct dentry *parent, struct qstr *entry, struct qstr *name) return 0; } -const struct dentry_operations adfs_dentry_operations = { +struct dentry_operations adfs_dentry_operations = { .d_hash = adfs_hash, .d_compare = adfs_compare, }; diff --git a/trunk/fs/affs/affs.h b/trunk/fs/affs/affs.h index 1a2d5e3c7f4e..e9ec915f7553 100644 --- a/trunk/fs/affs/affs.h +++ b/trunk/fs/affs/affs.h @@ -199,7 +199,8 @@ extern const struct address_space_operations affs_symlink_aops; extern const struct address_space_operations affs_aops; extern const struct address_space_operations affs_aops_ofs; -extern const struct dentry_operations affs_dentry_operations; +extern struct dentry_operations affs_dentry_operations; +extern struct dentry_operations affs_dentry_operations_intl; static inline void affs_set_blocksize(struct super_block *sb, int size) diff --git a/trunk/fs/affs/amigaffs.c b/trunk/fs/affs/amigaffs.c index 7d0f0a30f7a3..805573005de6 100644 --- a/trunk/fs/affs/amigaffs.c +++ b/trunk/fs/affs/amigaffs.c @@ -179,18 +179,14 @@ affs_remove_link(struct dentry *dentry) affs_lock_dir(dir); affs_fix_dcache(dentry, link_ino); retval = affs_remove_hash(dir, link_bh); - if (retval) { - affs_unlock_dir(dir); + if (retval) goto done; - } mark_buffer_dirty_inode(link_bh, inode); memcpy(AFFS_TAIL(sb, bh)->name, AFFS_TAIL(sb, link_bh)->name, 32); retval = affs_insert_hash(dir, bh); - if (retval) { - affs_unlock_dir(dir); + if (retval) goto done; - } mark_buffer_dirty_inode(bh, inode); affs_unlock_dir(dir); diff --git a/trunk/fs/affs/namei.c b/trunk/fs/affs/namei.c index 960d336ec694..cfcf1b6cf82b 100644 --- a/trunk/fs/affs/namei.c +++ b/trunk/fs/affs/namei.c @@ -19,12 +19,12 @@ static int affs_intl_toupper(int ch); static int affs_intl_hash_dentry(struct dentry *, struct qstr *); static int affs_intl_compare_dentry(struct dentry *, struct qstr *, struct qstr *); -const struct dentry_operations affs_dentry_operations = { +struct dentry_operations affs_dentry_operations = { .d_hash = affs_hash_dentry, .d_compare = affs_compare_dentry, }; -static const struct dentry_operations affs_intl_dentry_operations = { +static struct dentry_operations affs_intl_dentry_operations = { .d_hash = affs_intl_hash_dentry, .d_compare = affs_intl_compare_dentry, }; diff --git a/trunk/fs/afs/dir.c b/trunk/fs/afs/dir.c index 9bd757774c9e..99cf390641f7 100644 --- a/trunk/fs/afs/dir.c +++ b/trunk/fs/afs/dir.c @@ -62,7 +62,7 @@ const struct inode_operations afs_dir_inode_operations = { .setattr = afs_setattr, }; -static const struct dentry_operations afs_fs_dentry_operations = { +static struct dentry_operations afs_fs_dentry_operations = { .d_revalidate = afs_d_revalidate, .d_delete = afs_d_delete, .d_release = afs_d_release, diff --git a/trunk/fs/anon_inodes.c b/trunk/fs/anon_inodes.c index 1dd96d4406c0..3bbdb9d02376 100644 --- a/trunk/fs/anon_inodes.c +++ b/trunk/fs/anon_inodes.c @@ -48,7 +48,7 @@ static struct file_system_type anon_inode_fs_type = { .get_sb = anon_inodefs_get_sb, .kill_sb = kill_anon_super, }; -static const struct dentry_operations anon_inodefs_dentry_operations = { +static struct dentry_operations anon_inodefs_dentry_operations = { .d_delete = anon_inodefs_delete_dentry, }; diff --git a/trunk/fs/attr.c b/trunk/fs/attr.c index 9fe1b1bd30a8..f4360192a938 100644 --- a/trunk/fs/attr.c +++ b/trunk/fs/attr.c @@ -173,8 +173,7 @@ int notify_change(struct dentry * dentry, struct iattr * attr) if (!error) { if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) || (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) - error = vfs_dq_transfer(inode, attr) ? - -EDQUOT : 0; + error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0; if (!error) error = inode_setattr(inode, attr); } diff --git a/trunk/fs/autofs/root.c b/trunk/fs/autofs/root.c index 4a1401cea0a1..8aacade56956 100644 --- a/trunk/fs/autofs/root.c +++ b/trunk/fs/autofs/root.c @@ -192,7 +192,7 @@ static int autofs_revalidate(struct dentry * dentry, struct nameidata *nd) return 1; } -static const struct dentry_operations autofs_dentry_operations = { +static struct dentry_operations autofs_dentry_operations = { .d_revalidate = autofs_revalidate, }; diff --git a/trunk/fs/autofs4/inode.c b/trunk/fs/autofs4/inode.c index 69c8142da838..716e12b627b2 100644 --- a/trunk/fs/autofs4/inode.c +++ b/trunk/fs/autofs4/inode.c @@ -310,7 +310,7 @@ static struct autofs_info *autofs4_mkroot(struct autofs_sb_info *sbi) return ino; } -static const struct dentry_operations autofs4_sb_dentry_operations = { +static struct dentry_operations autofs4_sb_dentry_operations = { .d_release = autofs4_dentry_release, }; diff --git a/trunk/fs/autofs4/root.c b/trunk/fs/autofs4/root.c index 74b1469a9504..2a41c2a7fc52 100644 --- a/trunk/fs/autofs4/root.c +++ b/trunk/fs/autofs4/root.c @@ -349,13 +349,13 @@ void autofs4_dentry_release(struct dentry *de) } /* For dentries of directories in the root dir */ -static const struct dentry_operations autofs4_root_dentry_operations = { +static struct dentry_operations autofs4_root_dentry_operations = { .d_revalidate = autofs4_revalidate, .d_release = autofs4_dentry_release, }; /* For other dentries */ -static const struct dentry_operations autofs4_dentry_operations = { +static struct dentry_operations autofs4_dentry_operations = { .d_revalidate = autofs4_revalidate, .d_release = autofs4_dentry_release, }; diff --git a/trunk/fs/block_dev.c b/trunk/fs/block_dev.c index 8c3c6899ccf3..b3c1efff5e1d 100644 --- a/trunk/fs/block_dev.c +++ b/trunk/fs/block_dev.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -175,151 +174,6 @@ blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, iov, offset, nr_segs, blkdev_get_blocks, NULL); } -/* - * Write out and wait upon all the dirty data associated with a block - * device via its mapping. Does not take the superblock lock. - */ -int sync_blockdev(struct block_device *bdev) -{ - int ret = 0; - - if (bdev) - ret = filemap_write_and_wait(bdev->bd_inode->i_mapping); - return ret; -} -EXPORT_SYMBOL(sync_blockdev); - -/* - * Write out and wait upon all dirty data associated with this - * device. Filesystem data as well as the underlying block - * device. Takes the superblock lock. - */ -int fsync_bdev(struct block_device *bdev) -{ - struct super_block *sb = get_super(bdev); - if (sb) { - int res = fsync_super(sb); - drop_super(sb); - return res; - } - return sync_blockdev(bdev); -} - -/** - * freeze_bdev -- lock a filesystem and force it into a consistent state - * @bdev: blockdevice to lock - * - * This takes the block device bd_mount_sem to make sure no new mounts - * happen on bdev until thaw_bdev() is called. - * If a superblock is found on this device, we take the s_umount semaphore - * on it to make sure nobody unmounts until the snapshot creation is done. - * The reference counter (bd_fsfreeze_count) guarantees that only the last - * unfreeze process can unfreeze the frozen filesystem actually when multiple - * freeze requests arrive simultaneously. It counts up in freeze_bdev() and - * count down in thaw_bdev(). When it becomes 0, thaw_bdev() will unfreeze - * actually. - */ -struct super_block *freeze_bdev(struct block_device *bdev) -{ - struct super_block *sb; - int error = 0; - - mutex_lock(&bdev->bd_fsfreeze_mutex); - if (bdev->bd_fsfreeze_count > 0) { - bdev->bd_fsfreeze_count++; - sb = get_super(bdev); - mutex_unlock(&bdev->bd_fsfreeze_mutex); - return sb; - } - bdev->bd_fsfreeze_count++; - - down(&bdev->bd_mount_sem); - sb = get_super(bdev); - if (sb && !(sb->s_flags & MS_RDONLY)) { - sb->s_frozen = SB_FREEZE_WRITE; - smp_wmb(); - - __fsync_super(sb); - - sb->s_frozen = SB_FREEZE_TRANS; - smp_wmb(); - - sync_blockdev(sb->s_bdev); - - if (sb->s_op->freeze_fs) { - error = sb->s_op->freeze_fs(sb); - if (error) { - printk(KERN_ERR - "VFS:Filesystem freeze failed\n"); - sb->s_frozen = SB_UNFROZEN; - drop_super(sb); - up(&bdev->bd_mount_sem); - bdev->bd_fsfreeze_count--; - mutex_unlock(&bdev->bd_fsfreeze_mutex); - return ERR_PTR(error); - } - } - } - - sync_blockdev(bdev); - mutex_unlock(&bdev->bd_fsfreeze_mutex); - - return sb; /* thaw_bdev releases s->s_umount and bd_mount_sem */ -} -EXPORT_SYMBOL(freeze_bdev); - -/** - * thaw_bdev -- unlock filesystem - * @bdev: blockdevice to unlock - * @sb: associated superblock - * - * Unlocks the filesystem and marks it writeable again after freeze_bdev(). - */ -int thaw_bdev(struct block_device *bdev, struct super_block *sb) -{ - int error = 0; - - mutex_lock(&bdev->bd_fsfreeze_mutex); - if (!bdev->bd_fsfreeze_count) { - mutex_unlock(&bdev->bd_fsfreeze_mutex); - return -EINVAL; - } - - bdev->bd_fsfreeze_count--; - if (bdev->bd_fsfreeze_count > 0) { - if (sb) - drop_super(sb); - mutex_unlock(&bdev->bd_fsfreeze_mutex); - return 0; - } - - if (sb) { - BUG_ON(sb->s_bdev != bdev); - if (!(sb->s_flags & MS_RDONLY)) { - if (sb->s_op->unfreeze_fs) { - error = sb->s_op->unfreeze_fs(sb); - if (error) { - printk(KERN_ERR - "VFS:Filesystem thaw failed\n"); - sb->s_frozen = SB_FREEZE_TRANS; - bdev->bd_fsfreeze_count++; - mutex_unlock(&bdev->bd_fsfreeze_mutex); - return error; - } - } - sb->s_frozen = SB_UNFROZEN; - smp_wmb(); - wake_up(&sb->s_wait_unfrozen); - } - drop_super(sb); - } - - up(&bdev->bd_mount_sem); - mutex_unlock(&bdev->bd_fsfreeze_mutex); - return 0; -} -EXPORT_SYMBOL(thaw_bdev); - static int blkdev_writepage(struct page *page, struct writeback_control *wbc) { return block_write_full_page(page, blkdev_get_block, wbc); diff --git a/trunk/fs/buffer.c b/trunk/fs/buffer.c index a2fd743d97cb..891e1c78e4f1 100644 --- a/trunk/fs/buffer.c +++ b/trunk/fs/buffer.c @@ -165,6 +165,151 @@ void end_buffer_write_sync(struct buffer_head *bh, int uptodate) put_bh(bh); } +/* + * Write out and wait upon all the dirty data associated with a block + * device via its mapping. Does not take the superblock lock. + */ +int sync_blockdev(struct block_device *bdev) +{ + int ret = 0; + + if (bdev) + ret = filemap_write_and_wait(bdev->bd_inode->i_mapping); + return ret; +} +EXPORT_SYMBOL(sync_blockdev); + +/* + * Write out and wait upon all dirty data associated with this + * device. Filesystem data as well as the underlying block + * device. Takes the superblock lock. + */ +int fsync_bdev(struct block_device *bdev) +{ + struct super_block *sb = get_super(bdev); + if (sb) { + int res = fsync_super(sb); + drop_super(sb); + return res; + } + return sync_blockdev(bdev); +} + +/** + * freeze_bdev -- lock a filesystem and force it into a consistent state + * @bdev: blockdevice to lock + * + * This takes the block device bd_mount_sem to make sure no new mounts + * happen on bdev until thaw_bdev() is called. + * If a superblock is found on this device, we take the s_umount semaphore + * on it to make sure nobody unmounts until the snapshot creation is done. + * The reference counter (bd_fsfreeze_count) guarantees that only the last + * unfreeze process can unfreeze the frozen filesystem actually when multiple + * freeze requests arrive simultaneously. It counts up in freeze_bdev() and + * count down in thaw_bdev(). When it becomes 0, thaw_bdev() will unfreeze + * actually. + */ +struct super_block *freeze_bdev(struct block_device *bdev) +{ + struct super_block *sb; + int error = 0; + + mutex_lock(&bdev->bd_fsfreeze_mutex); + if (bdev->bd_fsfreeze_count > 0) { + bdev->bd_fsfreeze_count++; + sb = get_super(bdev); + mutex_unlock(&bdev->bd_fsfreeze_mutex); + return sb; + } + bdev->bd_fsfreeze_count++; + + down(&bdev->bd_mount_sem); + sb = get_super(bdev); + if (sb && !(sb->s_flags & MS_RDONLY)) { + sb->s_frozen = SB_FREEZE_WRITE; + smp_wmb(); + + __fsync_super(sb); + + sb->s_frozen = SB_FREEZE_TRANS; + smp_wmb(); + + sync_blockdev(sb->s_bdev); + + if (sb->s_op->freeze_fs) { + error = sb->s_op->freeze_fs(sb); + if (error) { + printk(KERN_ERR + "VFS:Filesystem freeze failed\n"); + sb->s_frozen = SB_UNFROZEN; + drop_super(sb); + up(&bdev->bd_mount_sem); + bdev->bd_fsfreeze_count--; + mutex_unlock(&bdev->bd_fsfreeze_mutex); + return ERR_PTR(error); + } + } + } + + sync_blockdev(bdev); + mutex_unlock(&bdev->bd_fsfreeze_mutex); + + return sb; /* thaw_bdev releases s->s_umount and bd_mount_sem */ +} +EXPORT_SYMBOL(freeze_bdev); + +/** + * thaw_bdev -- unlock filesystem + * @bdev: blockdevice to unlock + * @sb: associated superblock + * + * Unlocks the filesystem and marks it writeable again after freeze_bdev(). + */ +int thaw_bdev(struct block_device *bdev, struct super_block *sb) +{ + int error = 0; + + mutex_lock(&bdev->bd_fsfreeze_mutex); + if (!bdev->bd_fsfreeze_count) { + mutex_unlock(&bdev->bd_fsfreeze_mutex); + return -EINVAL; + } + + bdev->bd_fsfreeze_count--; + if (bdev->bd_fsfreeze_count > 0) { + if (sb) + drop_super(sb); + mutex_unlock(&bdev->bd_fsfreeze_mutex); + return 0; + } + + if (sb) { + BUG_ON(sb->s_bdev != bdev); + if (!(sb->s_flags & MS_RDONLY)) { + if (sb->s_op->unfreeze_fs) { + error = sb->s_op->unfreeze_fs(sb); + if (error) { + printk(KERN_ERR + "VFS:Filesystem thaw failed\n"); + sb->s_frozen = SB_FREEZE_TRANS; + bdev->bd_fsfreeze_count++; + mutex_unlock(&bdev->bd_fsfreeze_mutex); + return error; + } + } + sb->s_frozen = SB_UNFROZEN; + smp_wmb(); + wake_up(&sb->s_wait_unfrozen); + } + drop_super(sb); + } + + up(&bdev->bd_mount_sem); + mutex_unlock(&bdev->bd_fsfreeze_mutex); + return 0; +} +EXPORT_SYMBOL(thaw_bdev); + /* * Various filesystems appear to want __find_get_block to be non-blocking. * But it's the page lock which protects the buffers. To get around this, diff --git a/trunk/fs/cifs/cifsfs.c b/trunk/fs/cifs/cifsfs.c index 38491fd3871d..13ea53251dcf 100644 --- a/trunk/fs/cifs/cifsfs.c +++ b/trunk/fs/cifs/cifsfs.c @@ -606,8 +606,7 @@ cifs_get_sb(struct file_system_type *fs_type, return rc; } sb->s_flags |= MS_ACTIVE; - simple_set_mnt(mnt, sb); - return 0; + return simple_set_mnt(mnt, sb); } static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov, diff --git a/trunk/fs/cifs/cifsfs.h b/trunk/fs/cifs/cifsfs.h index 77e190dc2883..2b1d28a9ee28 100644 --- a/trunk/fs/cifs/cifsfs.h +++ b/trunk/fs/cifs/cifsfs.h @@ -78,8 +78,8 @@ extern int cifs_dir_open(struct inode *inode, struct file *file); extern int cifs_readdir(struct file *file, void *direntry, filldir_t filldir); /* Functions related to dir entries */ -extern const struct dentry_operations cifs_dentry_ops; -extern const struct dentry_operations cifs_ci_dentry_ops; +extern struct dentry_operations cifs_dentry_ops; +extern struct dentry_operations cifs_ci_dentry_ops; /* Functions related to symlinks */ extern void *cifs_follow_link(struct dentry *direntry, struct nameidata *nd); diff --git a/trunk/fs/cifs/dir.c b/trunk/fs/cifs/dir.c index 2f35cccfcd8d..f9b6f68be976 100644 --- a/trunk/fs/cifs/dir.c +++ b/trunk/fs/cifs/dir.c @@ -701,7 +701,7 @@ cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd) return rc; } */ -const struct dentry_operations cifs_dentry_ops = { +struct dentry_operations cifs_dentry_ops = { .d_revalidate = cifs_d_revalidate, /* d_delete: cifs_d_delete, */ /* not needed except for debugging */ }; @@ -739,7 +739,7 @@ static int cifs_ci_compare(struct dentry *dentry, struct qstr *a, return 1; } -const struct dentry_operations cifs_ci_dentry_ops = { +struct dentry_operations cifs_ci_dentry_ops = { .d_revalidate = cifs_d_revalidate, .d_hash = cifs_ci_hash, .d_compare = cifs_ci_compare, diff --git a/trunk/fs/coda/dir.c b/trunk/fs/coda/dir.c index 4bb9d0a5decc..75b1fa90b2cb 100644 --- a/trunk/fs/coda/dir.c +++ b/trunk/fs/coda/dir.c @@ -59,7 +59,7 @@ static int coda_return_EIO(void) } #define CODA_EIO_ERROR ((void *) (coda_return_EIO)) -static const struct dentry_operations coda_dentry_operations = +static struct dentry_operations coda_dentry_operations = { .d_revalidate = coda_dentry_revalidate, .d_delete = coda_dentry_delete, diff --git a/trunk/fs/compat.c b/trunk/fs/compat.c index 5e374aad33f7..0949b43794a4 100644 --- a/trunk/fs/compat.c +++ b/trunk/fs/compat.c @@ -378,34 +378,6 @@ asmlinkage long compat_sys_fstatfs64(unsigned int fd, compat_size_t sz, struct c return error; } -/* - * This is a copy of sys_ustat, just dealing with a structure layout. - * Given how simple this syscall is that apporach is more maintainable - * than the various conversion hacks. - */ -asmlinkage long compat_sys_ustat(unsigned dev, struct compat_ustat __user *u) -{ - struct super_block *sb; - struct compat_ustat tmp; - struct kstatfs sbuf; - int err; - - sb = user_get_super(new_decode_dev(dev)); - if (!sb) - return -EINVAL; - err = vfs_statfs(sb->s_root, &sbuf); - drop_super(sb); - if (err) - return err; - - memset(&tmp, 0, sizeof(struct compat_ustat)); - tmp.f_tfree = sbuf.f_bfree; - tmp.f_tinode = sbuf.f_ffree; - if (copy_to_user(u, &tmp, sizeof(struct compat_ustat))) - return -EFAULT; - return 0; -} - static int get_compat_flock(struct flock *kfl, struct compat_flock __user *ufl) { if (!access_ok(VERIFY_READ, ufl, sizeof(*ufl)) || diff --git a/trunk/fs/configfs/dir.c b/trunk/fs/configfs/dir.c index 05373db21a4e..8e93341f3e82 100644 --- a/trunk/fs/configfs/dir.c +++ b/trunk/fs/configfs/dir.c @@ -72,7 +72,7 @@ static int configfs_d_delete(struct dentry *dentry) return 1; } -static const struct dentry_operations configfs_dentry_ops = { +static struct dentry_operations configfs_dentry_ops = { .d_iput = configfs_d_iput, /* simple_delete_dentry() isn't exported */ .d_delete = configfs_d_delete, diff --git a/trunk/fs/dcache.c b/trunk/fs/dcache.c index 90bbd7e1b116..07e2d4a44bda 100644 --- a/trunk/fs/dcache.c +++ b/trunk/fs/dcache.c @@ -1247,18 +1247,15 @@ struct dentry *d_add_ci(struct dentry *dentry, struct inode *inode, struct dentry *found; struct dentry *new; - /* - * First check if a dentry matching the name already exists, - * if not go ahead and create it now. - */ + /* Does a dentry matching the name exist already? */ found = d_hash_and_lookup(dentry->d_parent, name); + /* If not, create it now and return */ if (!found) { new = d_alloc(dentry->d_parent, name); if (!new) { error = -ENOMEM; goto err_out; } - found = d_splice_alias(inode, new); if (found) { dput(new); @@ -1266,46 +1263,61 @@ struct dentry *d_add_ci(struct dentry *dentry, struct inode *inode, } return new; } - - /* - * If a matching dentry exists, and it's not negative use it. - * - * Decrement the reference count to balance the iget() done - * earlier on. - */ + /* Matching dentry exists, check if it is negative. */ if (found->d_inode) { if (unlikely(found->d_inode != inode)) { /* This can't happen because bad inodes are unhashed. */ BUG_ON(!is_bad_inode(inode)); BUG_ON(!is_bad_inode(found->d_inode)); } + /* + * Already have the inode and the dentry attached, decrement + * the reference count to balance the iget() done + * earlier on. We found the dentry using d_lookup() so it + * cannot be disconnected and thus we do not need to worry + * about any NFS/disconnectedness issues here. + */ iput(inode); return found; } - /* * Negative dentry: instantiate it unless the inode is a directory and - * already has a dentry. + * has a 'disconnected' dentry (i.e. IS_ROOT and DCACHE_DISCONNECTED), + * in which case d_move() that in place of the found dentry. */ + if (!S_ISDIR(inode->i_mode)) { + /* Not a directory; everything is easy. */ + d_instantiate(found, inode); + return found; + } spin_lock(&dcache_lock); - if (!S_ISDIR(inode->i_mode) || list_empty(&inode->i_dentry)) { + if (list_empty(&inode->i_dentry)) { + /* + * Directory without a 'disconnected' dentry; we need to do + * d_instantiate() by hand because it takes dcache_lock which + * we already hold. + */ __d_instantiate(found, inode); spin_unlock(&dcache_lock); security_d_instantiate(found, inode); return found; } - /* - * In case a directory already has a (disconnected) entry grab a - * reference to it, move it in place and use it. + * Directory with a 'disconnected' dentry; get a reference to the + * 'disconnected' dentry. */ new = list_entry(inode->i_dentry.next, struct dentry, d_alias); dget_locked(new); spin_unlock(&dcache_lock); + /* Do security vodoo. */ security_d_instantiate(found, inode); + /* Move new in place of found. */ d_move(new, found); + /* Balance the iget() we did above. */ iput(inode); + /* Throw away found. */ dput(found); + /* Use new as the actual dentry. */ return new; err_out: diff --git a/trunk/fs/devpts/inode.c b/trunk/fs/devpts/inode.c index 63a4a59e4148..bff4052b05e7 100644 --- a/trunk/fs/devpts/inode.c +++ b/trunk/fs/devpts/inode.c @@ -322,81 +322,177 @@ static int compare_init_pts_sb(struct super_block *s, void *p) } /* - * devpts_get_sb() + * Safely parse the mount options in @data and update @opts. * - * If the '-o newinstance' mount option was specified, mount a new - * (private) instance of devpts. PTYs created in this instance are - * independent of the PTYs in other devpts instances. + * devpts ends up parsing options two times during mount, due to the + * two modes of operation it supports. The first parse occurs in + * devpts_get_sb() when determining the mode (single-instance or + * multi-instance mode). The second parse happens in devpts_remount() + * or new_pts_mount() depending on the mode. * - * If the '-o newinstance' option was not specified, mount/remount the - * initial kernel mount of devpts. This type of mount gives the - * legacy, single-instance semantics. + * Parsing of options modifies the @data making subsequent parsing + * incorrect. So make a local copy of @data and parse it. * - * The 'newinstance' option is needed to support multiple namespace - * semantics in devpts while preserving backward compatibility of the - * current 'single-namespace' semantics. i.e all mounts of devpts - * without the 'newinstance' mount option should bind to the initial - * kernel mount, like get_sb_single(). + * Return: 0 On success, -errno on error + */ +static int safe_parse_mount_options(void *data, struct pts_mount_opts *opts) +{ + int rc; + void *datacp; + + if (!data) + return 0; + + /* Use kstrdup() ? */ + datacp = kmalloc(PAGE_SIZE, GFP_KERNEL); + if (!datacp) + return -ENOMEM; + + memcpy(datacp, data, PAGE_SIZE); + rc = parse_mount_options((char *)datacp, PARSE_MOUNT, opts); + kfree(datacp); + + return rc; +} + +/* + * Mount a new (private) instance of devpts. PTYs created in this + * instance are independent of the PTYs in other devpts instances. + */ +static int new_pts_mount(struct file_system_type *fs_type, int flags, + void *data, struct vfsmount *mnt) +{ + int err; + struct pts_fs_info *fsi; + struct pts_mount_opts *opts; + + err = get_sb_nodev(fs_type, flags, data, devpts_fill_super, mnt); + if (err) + return err; + + fsi = DEVPTS_SB(mnt->mnt_sb); + opts = &fsi->mount_opts; + + err = parse_mount_options(data, PARSE_MOUNT, opts); + if (err) + goto fail; + + err = mknod_ptmx(mnt->mnt_sb); + if (err) + goto fail; + + return 0; + +fail: + dput(mnt->mnt_sb->s_root); + deactivate_super(mnt->mnt_sb); + return err; +} + +/* + * Check if 'newinstance' mount option was specified in @data. * - * Mounts with 'newinstance' option create a new, private namespace. + * Return: -errno on error (eg: invalid mount options specified) + * : 1 if 'newinstance' mount option was specified + * : 0 if 'newinstance' mount option was NOT specified + */ +static int is_new_instance_mount(void *data) +{ + int rc; + struct pts_mount_opts opts; + + if (!data) + return 0; + + rc = safe_parse_mount_options(data, &opts); + if (!rc) + rc = opts.newinstance; + + return rc; +} + +/* + * get_init_pts_sb() + * + * This interface is needed to support multiple namespace semantics in + * devpts while preserving backward compatibility of the current 'single- + * namespace' semantics. i.e all mounts of devpts without the 'newinstance' + * mount option should bind to the initial kernel mount, like + * get_sb_single(). * - * NOTE: + * Mounts with 'newinstance' option create a new private namespace. * - * For single-mount semantics, devpts cannot use get_sb_single(), + * But for single-mount semantics, devpts cannot use get_sb_single(), * because get_sb_single()/sget() find and use the super-block from * the most recent mount of devpts. But that recent mount may be a * 'newinstance' mount and get_sb_single() would pick the newinstance * super-block instead of the initial super-block. + * + * This interface is identical to get_sb_single() except that it + * consistently selects the 'single-namespace' superblock even in the + * presence of the private namespace (i.e 'newinstance') super-blocks. */ -static int devpts_get_sb(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data, struct vfsmount *mnt) +static int get_init_pts_sb(struct file_system_type *fs_type, int flags, + void *data, struct vfsmount *mnt) { - int error; - struct pts_mount_opts opts; struct super_block *s; + int error; - memset(&opts, 0, sizeof(opts)); - if (data) { - error = parse_mount_options(data, PARSE_MOUNT, &opts); - if (error) - return error; - } - - if (opts.newinstance) - s = sget(fs_type, NULL, set_anon_super, NULL); - else - s = sget(fs_type, compare_init_pts_sb, set_anon_super, NULL); - + s = sget(fs_type, compare_init_pts_sb, set_anon_super, NULL); if (IS_ERR(s)) return PTR_ERR(s); if (!s->s_root) { s->s_flags = flags; error = devpts_fill_super(s, data, flags & MS_SILENT ? 1 : 0); - if (error) - goto out_undo_sget; + if (error) { + up_write(&s->s_umount); + deactivate_super(s); + return error; + } s->s_flags |= MS_ACTIVE; } + do_remount_sb(s, flags, data, 0); + return simple_set_mnt(mnt, s); +} - simple_set_mnt(mnt, s); +/* + * Mount or remount the initial kernel mount of devpts. This type of + * mount maintains the legacy, single-instance semantics, while the + * kernel still allows multiple-instances. + */ +static int init_pts_mount(struct file_system_type *fs_type, int flags, + void *data, struct vfsmount *mnt) +{ + int err; - memcpy(&(DEVPTS_SB(s))->mount_opts, &opts, sizeof(opts)); + err = get_init_pts_sb(fs_type, flags, data, mnt); + if (err) + return err; - error = mknod_ptmx(s); - if (error) - goto out_dput; + err = mknod_ptmx(mnt->mnt_sb); + if (err) { + dput(mnt->mnt_sb->s_root); + deactivate_super(mnt->mnt_sb); + } - return 0; + return err; +} + +static int devpts_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, struct vfsmount *mnt) +{ + int new; -out_dput: - dput(s->s_root); + new = is_new_instance_mount(data); + if (new < 0) + return new; -out_undo_sget: - up_write(&s->s_umount); - deactivate_super(s); - return error; -} + if (new) + return new_pts_mount(fs_type, flags, data, mnt); + return init_pts_mount(fs_type, flags, data, mnt); +} #else /* * This supports only the legacy single-instance semantics (no diff --git a/trunk/fs/dlm/dir.c b/trunk/fs/dlm/dir.c index 858fba14aaa6..92969f879a17 100644 --- a/trunk/fs/dlm/dir.c +++ b/trunk/fs/dlm/dir.c @@ -156,7 +156,7 @@ void dlm_dir_remove_entry(struct dlm_ls *ls, int nodeid, char *name, int namelen bucket = dir_hash(ls, name, namelen); - spin_lock(&ls->ls_dirtbl[bucket].lock); + write_lock(&ls->ls_dirtbl[bucket].lock); de = search_bucket(ls, name, namelen, bucket); @@ -173,7 +173,7 @@ void dlm_dir_remove_entry(struct dlm_ls *ls, int nodeid, char *name, int namelen list_del(&de->list); kfree(de); out: - spin_unlock(&ls->ls_dirtbl[bucket].lock); + write_unlock(&ls->ls_dirtbl[bucket].lock); } void dlm_dir_clear(struct dlm_ls *ls) @@ -185,14 +185,14 @@ void dlm_dir_clear(struct dlm_ls *ls) DLM_ASSERT(list_empty(&ls->ls_recover_list), ); for (i = 0; i < ls->ls_dirtbl_size; i++) { - spin_lock(&ls->ls_dirtbl[i].lock); + write_lock(&ls->ls_dirtbl[i].lock); head = &ls->ls_dirtbl[i].list; while (!list_empty(head)) { de = list_entry(head->next, struct dlm_direntry, list); list_del(&de->list); put_free_de(ls, de); } - spin_unlock(&ls->ls_dirtbl[i].lock); + write_unlock(&ls->ls_dirtbl[i].lock); } } @@ -307,17 +307,17 @@ static int get_entry(struct dlm_ls *ls, int nodeid, char *name, bucket = dir_hash(ls, name, namelen); - spin_lock(&ls->ls_dirtbl[bucket].lock); + write_lock(&ls->ls_dirtbl[bucket].lock); de = search_bucket(ls, name, namelen, bucket); if (de) { *r_nodeid = de->master_nodeid; - spin_unlock(&ls->ls_dirtbl[bucket].lock); + write_unlock(&ls->ls_dirtbl[bucket].lock); if (*r_nodeid == nodeid) return -EEXIST; return 0; } - spin_unlock(&ls->ls_dirtbl[bucket].lock); + write_unlock(&ls->ls_dirtbl[bucket].lock); if (namelen > DLM_RESNAME_MAXLEN) return -EINVAL; @@ -330,7 +330,7 @@ static int get_entry(struct dlm_ls *ls, int nodeid, char *name, de->length = namelen; memcpy(de->name, name, namelen); - spin_lock(&ls->ls_dirtbl[bucket].lock); + write_lock(&ls->ls_dirtbl[bucket].lock); tmp = search_bucket(ls, name, namelen, bucket); if (tmp) { kfree(de); @@ -339,7 +339,7 @@ static int get_entry(struct dlm_ls *ls, int nodeid, char *name, list_add_tail(&de->list, &ls->ls_dirtbl[bucket].list); } *r_nodeid = de->master_nodeid; - spin_unlock(&ls->ls_dirtbl[bucket].lock); + write_unlock(&ls->ls_dirtbl[bucket].lock); return 0; } diff --git a/trunk/fs/dlm/dlm_internal.h b/trunk/fs/dlm/dlm_internal.h index d01ca0a711db..076e86f38bc8 100644 --- a/trunk/fs/dlm/dlm_internal.h +++ b/trunk/fs/dlm/dlm_internal.h @@ -99,7 +99,7 @@ struct dlm_direntry { struct dlm_dirtable { struct list_head list; - spinlock_t lock; + rwlock_t lock; }; struct dlm_rsbtable { diff --git a/trunk/fs/dlm/lock.c b/trunk/fs/dlm/lock.c index 205ec95b347e..01e7d39c5fba 100644 --- a/trunk/fs/dlm/lock.c +++ b/trunk/fs/dlm/lock.c @@ -835,7 +835,7 @@ static int add_to_waiters(struct dlm_lkb *lkb, int mstype) lkb->lkb_wait_count++; hold_lkb(lkb); - log_debug(ls, "addwait %x cur %d overlap %d count %d f %x", + log_debug(ls, "add overlap %x cur %d new %d count %d flags %x", lkb->lkb_id, lkb->lkb_wait_type, mstype, lkb->lkb_wait_count, lkb->lkb_flags); goto out; @@ -851,7 +851,7 @@ static int add_to_waiters(struct dlm_lkb *lkb, int mstype) list_add(&lkb->lkb_wait_reply, &ls->ls_waiters); out: if (error) - log_error(ls, "addwait error %x %d flags %x %d %d %s", + log_error(ls, "add_to_waiters %x error %d flags %x %d %d %s", lkb->lkb_id, error, lkb->lkb_flags, mstype, lkb->lkb_wait_type, lkb->lkb_resource->res_name); mutex_unlock(&ls->ls_waiters_mutex); @@ -863,55 +863,23 @@ static int add_to_waiters(struct dlm_lkb *lkb, int mstype) request reply on the requestqueue) between dlm_recover_waiters_pre() which set RESEND and dlm_recover_waiters_post() */ -static int _remove_from_waiters(struct dlm_lkb *lkb, int mstype, - struct dlm_message *ms) +static int _remove_from_waiters(struct dlm_lkb *lkb, int mstype) { struct dlm_ls *ls = lkb->lkb_resource->res_ls; int overlap_done = 0; if (is_overlap_unlock(lkb) && (mstype == DLM_MSG_UNLOCK_REPLY)) { - log_debug(ls, "remwait %x unlock_reply overlap", lkb->lkb_id); lkb->lkb_flags &= ~DLM_IFL_OVERLAP_UNLOCK; overlap_done = 1; goto out_del; } if (is_overlap_cancel(lkb) && (mstype == DLM_MSG_CANCEL_REPLY)) { - log_debug(ls, "remwait %x cancel_reply overlap", lkb->lkb_id); lkb->lkb_flags &= ~DLM_IFL_OVERLAP_CANCEL; overlap_done = 1; goto out_del; } - /* Cancel state was preemptively cleared by a successful convert, - see next comment, nothing to do. */ - - if ((mstype == DLM_MSG_CANCEL_REPLY) && - (lkb->lkb_wait_type != DLM_MSG_CANCEL)) { - log_debug(ls, "remwait %x cancel_reply wait_type %d", - lkb->lkb_id, lkb->lkb_wait_type); - return -1; - } - - /* Remove for the convert reply, and premptively remove for the - cancel reply. A convert has been granted while there's still - an outstanding cancel on it (the cancel is moot and the result - in the cancel reply should be 0). We preempt the cancel reply - because the app gets the convert result and then can follow up - with another op, like convert. This subsequent op would see the - lingering state of the cancel and fail with -EBUSY. */ - - if ((mstype == DLM_MSG_CONVERT_REPLY) && - (lkb->lkb_wait_type == DLM_MSG_CONVERT) && - is_overlap_cancel(lkb) && ms && !ms->m_result) { - log_debug(ls, "remwait %x convert_reply zap overlap_cancel", - lkb->lkb_id); - lkb->lkb_wait_type = 0; - lkb->lkb_flags &= ~DLM_IFL_OVERLAP_CANCEL; - lkb->lkb_wait_count--; - goto out_del; - } - /* N.B. type of reply may not always correspond to type of original msg due to lookup->request optimization, verify others? */ @@ -920,8 +888,8 @@ static int _remove_from_waiters(struct dlm_lkb *lkb, int mstype, goto out_del; } - log_error(ls, "remwait error %x reply %d flags %x no wait_type", - lkb->lkb_id, mstype, lkb->lkb_flags); + log_error(ls, "remove_from_waiters lkid %x flags %x types %d %d", + lkb->lkb_id, lkb->lkb_flags, mstype, lkb->lkb_wait_type); return -1; out_del: @@ -931,7 +899,7 @@ static int _remove_from_waiters(struct dlm_lkb *lkb, int mstype, this would happen */ if (overlap_done && lkb->lkb_wait_type) { - log_error(ls, "remwait error %x reply %d wait_type %d overlap", + log_error(ls, "remove_from_waiters %x reply %d give up on %d", lkb->lkb_id, mstype, lkb->lkb_wait_type); lkb->lkb_wait_count--; lkb->lkb_wait_type = 0; @@ -953,7 +921,7 @@ static int remove_from_waiters(struct dlm_lkb *lkb, int mstype) int error; mutex_lock(&ls->ls_waiters_mutex); - error = _remove_from_waiters(lkb, mstype, NULL); + error = _remove_from_waiters(lkb, mstype); mutex_unlock(&ls->ls_waiters_mutex); return error; } @@ -968,7 +936,7 @@ static int remove_from_waiters_ms(struct dlm_lkb *lkb, struct dlm_message *ms) if (ms != &ls->ls_stub_ms) mutex_lock(&ls->ls_waiters_mutex); - error = _remove_from_waiters(lkb, ms->m_type, ms); + error = _remove_from_waiters(lkb, ms->m_type); if (ms != &ls->ls_stub_ms) mutex_unlock(&ls->ls_waiters_mutex); return error; @@ -2115,11 +2083,6 @@ static int validate_lock_args(struct dlm_ls *ls, struct dlm_lkb *lkb, lkb->lkb_timeout_cs = args->timeout; rv = 0; out: - if (rv) - log_debug(ls, "validate_lock_args %d %x %x %x %d %d %s", - rv, lkb->lkb_id, lkb->lkb_flags, args->flags, - lkb->lkb_status, lkb->lkb_wait_type, - lkb->lkb_resource->res_name); return rv; } @@ -2186,13 +2149,6 @@ static int validate_unlock_args(struct dlm_lkb *lkb, struct dlm_args *args) goto out; } - /* there's nothing to cancel */ - if (lkb->lkb_status == DLM_LKSTS_GRANTED && - !lkb->lkb_wait_type) { - rv = -EBUSY; - goto out; - } - switch (lkb->lkb_wait_type) { case DLM_MSG_LOOKUP: case DLM_MSG_REQUEST: diff --git a/trunk/fs/dlm/lockspace.c b/trunk/fs/dlm/lockspace.c index cd8e2df3c295..aa32e5f02493 100644 --- a/trunk/fs/dlm/lockspace.c +++ b/trunk/fs/dlm/lockspace.c @@ -487,7 +487,7 @@ static int new_lockspace(char *name, int namelen, void **lockspace, goto out_lkbfree; for (i = 0; i < size; i++) { INIT_LIST_HEAD(&ls->ls_dirtbl[i].list); - spin_lock_init(&ls->ls_dirtbl[i].lock); + rwlock_init(&ls->ls_dirtbl[i].lock); } INIT_LIST_HEAD(&ls->ls_waiters); diff --git a/trunk/fs/dlm/lowcomms.c b/trunk/fs/dlm/lowcomms.c index 609108a83267..103a5ebd1371 100644 --- a/trunk/fs/dlm/lowcomms.c +++ b/trunk/fs/dlm/lowcomms.c @@ -2,7 +2,7 @@ ******************************************************************************* ** ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved. +** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. ** ** This copyrighted material is made available to anyone wishing to use, ** modify, copy, or redistribute it subject to the terms and conditions @@ -21,7 +21,7 @@ * * Cluster nodes are referred to by their nodeids. nodeids are * simply 32 bit numbers to the locking module - if they need to - * be expanded for the cluster infrastructure then that is its + * be expanded for the cluster infrastructure then that is it's * responsibility. It is this layer's * responsibility to resolve these into IP address or * whatever it needs for inter-node communication. @@ -36,9 +36,9 @@ * of high load. Also, this way, the sending thread can collect together * messages bound for one node and send them in one block. * - * lowcomms will choose to use either TCP or SCTP as its transport layer + * lowcomms will choose to use wither TCP or SCTP as its transport layer * depending on the configuration variable 'protocol'. This should be set - * to 0 (default) for TCP or 1 for SCTP. It should be configured using a + * to 0 (default) for TCP or 1 for SCTP. It shouldbe configured using a * cluster-wide mechanism as it must be the same on all nodes of the cluster * for the DLM to function. * @@ -48,11 +48,11 @@ #include #include #include +#include #include #include #include #include -#include #include "dlm_internal.h" #include "lowcomms.h" @@ -60,7 +60,6 @@ #include "config.h" #define NEEDED_RMEM (4*1024*1024) -#define CONN_HASH_SIZE 32 struct cbuf { unsigned int base; @@ -115,7 +114,6 @@ struct connection { int retries; #define MAX_CONNECT_RETRIES 3 int sctp_assoc; - struct hlist_node list; struct connection *othercon; struct work_struct rwork; /* Receive workqueue */ struct work_struct swork; /* Send workqueue */ @@ -140,37 +138,14 @@ static int dlm_local_count; static struct workqueue_struct *recv_workqueue; static struct workqueue_struct *send_workqueue; -static struct hlist_head connection_hash[CONN_HASH_SIZE]; +static DEFINE_IDR(connections_idr); static DEFINE_MUTEX(connections_lock); +static int max_nodeid; static struct kmem_cache *con_cache; static void process_recv_sockets(struct work_struct *work); static void process_send_sockets(struct work_struct *work); - -/* This is deliberately very simple because most clusters have simple - sequential nodeids, so we should be able to go straight to a connection - struct in the array */ -static inline int nodeid_hash(int nodeid) -{ - return nodeid & (CONN_HASH_SIZE-1); -} - -static struct connection *__find_con(int nodeid) -{ - int r; - struct hlist_node *h; - struct connection *con; - - r = nodeid_hash(nodeid); - - hlist_for_each_entry(con, h, &connection_hash[r], list) { - if (con->nodeid == nodeid) - return con; - } - return NULL; -} - /* * If 'allocation' is zero then we don't attempt to create a new * connection structure for this node. @@ -179,17 +154,31 @@ static struct connection *__nodeid2con(int nodeid, gfp_t alloc) { struct connection *con = NULL; int r; + int n; - con = __find_con(nodeid); + con = idr_find(&connections_idr, nodeid); if (con || !alloc) return con; + r = idr_pre_get(&connections_idr, alloc); + if (!r) + return NULL; + con = kmem_cache_zalloc(con_cache, alloc); if (!con) return NULL; - r = nodeid_hash(nodeid); - hlist_add_head(&con->list, &connection_hash[r]); + r = idr_get_new_above(&connections_idr, con, nodeid, &n); + if (r) { + kmem_cache_free(con_cache, con); + return NULL; + } + + if (n != nodeid) { + idr_remove(&connections_idr, n); + kmem_cache_free(con_cache, con); + return NULL; + } con->nodeid = nodeid; mutex_init(&con->sock_mutex); @@ -200,28 +189,17 @@ static struct connection *__nodeid2con(int nodeid, gfp_t alloc) /* Setup action pointers for child sockets */ if (con->nodeid) { - struct connection *zerocon = __find_con(0); + struct connection *zerocon = idr_find(&connections_idr, 0); con->connect_action = zerocon->connect_action; if (!con->rx_action) con->rx_action = zerocon->rx_action; } - return con; -} + if (nodeid > max_nodeid) + max_nodeid = nodeid; -/* Loop round all connections */ -static void foreach_conn(void (*conn_func)(struct connection *c)) -{ - int i; - struct hlist_node *h, *n; - struct connection *con; - - for (i = 0; i < CONN_HASH_SIZE; i++) { - hlist_for_each_entry_safe(con, h, n, &connection_hash[i], list){ - conn_func(con); - } - } + return con; } static struct connection *nodeid2con(int nodeid, gfp_t allocation) @@ -239,17 +217,14 @@ static struct connection *nodeid2con(int nodeid, gfp_t allocation) static struct connection *assoc2con(int assoc_id) { int i; - struct hlist_node *h; struct connection *con; mutex_lock(&connections_lock); - - for (i = 0 ; i < CONN_HASH_SIZE; i++) { - hlist_for_each_entry(con, h, &connection_hash[i], list) { - if (con && con->sctp_assoc == assoc_id) { - mutex_unlock(&connections_lock); - return con; - } + for (i=0; i<=max_nodeid; i++) { + con = __nodeid2con(i, 0); + if (con && con->sctp_assoc == assoc_id) { + mutex_unlock(&connections_lock); + return con; } } mutex_unlock(&connections_lock); @@ -275,7 +250,8 @@ static int nodeid_to_addr(int nodeid, struct sockaddr *retaddr) } else { struct sockaddr_in6 *in6 = (struct sockaddr_in6 *) &addr; struct sockaddr_in6 *ret6 = (struct sockaddr_in6 *) retaddr; - ipv6_addr_copy(&ret6->sin6_addr, &in6->sin6_addr); + memcpy(&ret6->sin6_addr, &in6->sin6_addr, + sizeof(in6->sin6_addr)); } return 0; @@ -400,23 +376,25 @@ static void sctp_send_shutdown(sctp_assoc_t associd) log_print("send EOF to node failed: %d", ret); } -static void sctp_init_failed_foreach(struct connection *con) -{ - con->sctp_assoc = 0; - if (test_and_clear_bit(CF_CONNECT_PENDING, &con->flags)) { - if (!test_and_set_bit(CF_WRITE_PENDING, &con->flags)) - queue_work(send_workqueue, &con->swork); - } -} - /* INIT failed but we don't know which node... restart INIT on all pending nodes */ static void sctp_init_failed(void) { - mutex_lock(&connections_lock); - - foreach_conn(sctp_init_failed_foreach); + int i; + struct connection *con; + mutex_lock(&connections_lock); + for (i=1; i<=max_nodeid; i++) { + con = __nodeid2con(i, 0); + if (!con) + continue; + con->sctp_assoc = 0; + if (test_and_clear_bit(CF_CONNECT_PENDING, &con->flags)) { + if (!test_and_set_bit(CF_WRITE_PENDING, &con->flags)) { + queue_work(send_workqueue, &con->swork); + } + } + } mutex_unlock(&connections_lock); } @@ -1335,10 +1313,13 @@ static void send_to_sock(struct connection *con) static void clean_one_writequeue(struct connection *con) { - struct writequeue_entry *e, *safe; + struct list_head *list; + struct list_head *temp; spin_lock(&con->writequeue_lock); - list_for_each_entry_safe(e, safe, &con->writequeue, list) { + list_for_each_safe(list, temp, &con->writequeue) { + struct writequeue_entry *e = + list_entry(list, struct writequeue_entry, list); list_del(&e->list); free_entry(e); } @@ -1388,7 +1369,14 @@ static void process_send_sockets(struct work_struct *work) /* Discard all entries on the write queues */ static void clean_writequeues(void) { - foreach_conn(clean_one_writequeue); + int nodeid; + + for (nodeid = 1; nodeid <= max_nodeid; nodeid++) { + struct connection *con = __nodeid2con(nodeid, 0); + + if (con) + clean_one_writequeue(con); + } } static void work_stop(void) @@ -1418,29 +1406,23 @@ static int work_start(void) return 0; } -static void stop_conn(struct connection *con) -{ - con->flags |= 0x0F; - if (con->sock) - con->sock->sk->sk_user_data = NULL; -} - -static void free_conn(struct connection *con) -{ - close_connection(con, true); - if (con->othercon) - kmem_cache_free(con_cache, con->othercon); - hlist_del(&con->list); - kmem_cache_free(con_cache, con); -} - void dlm_lowcomms_stop(void) { + int i; + struct connection *con; + /* Set all the flags to prevent any socket activity. */ mutex_lock(&connections_lock); - foreach_conn(stop_conn); + for (i = 0; i <= max_nodeid; i++) { + con = __nodeid2con(i, 0); + if (con) { + con->flags |= 0x0F; + if (con->sock) + con->sock->sk->sk_user_data = NULL; + } + } mutex_unlock(&connections_lock); work_stop(); @@ -1448,20 +1430,25 @@ void dlm_lowcomms_stop(void) mutex_lock(&connections_lock); clean_writequeues(); - foreach_conn(free_conn); - + for (i = 0; i <= max_nodeid; i++) { + con = __nodeid2con(i, 0); + if (con) { + close_connection(con, true); + if (con->othercon) + kmem_cache_free(con_cache, con->othercon); + kmem_cache_free(con_cache, con); + } + } + max_nodeid = 0; mutex_unlock(&connections_lock); kmem_cache_destroy(con_cache); + idr_init(&connections_idr); } int dlm_lowcomms_start(void) { int error = -EINVAL; struct connection *con; - int i; - - for (i = 0; i < CONN_HASH_SIZE; i++) - INIT_HLIST_HEAD(&connection_hash[i]); init_local(); if (!dlm_local_count) { diff --git a/trunk/fs/dlm/user.c b/trunk/fs/dlm/user.c index ebce994ab0b7..065149e84f42 100644 --- a/trunk/fs/dlm/user.c +++ b/trunk/fs/dlm/user.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2009 Red Hat, Inc. All rights reserved. + * Copyright (C) 2006-2008 Red Hat, Inc. All rights reserved. * * This copyrighted material is made available to anyone wishing to use, * modify, copy, or redistribute it subject to the terms and conditions @@ -84,7 +84,7 @@ struct dlm_lock_result32 { static void compat_input(struct dlm_write_request *kb, struct dlm_write_request32 *kb32, - int namelen) + size_t count) { kb->version[0] = kb32->version[0]; kb->version[1] = kb32->version[1]; @@ -96,7 +96,8 @@ static void compat_input(struct dlm_write_request *kb, kb->cmd == DLM_USER_REMOVE_LOCKSPACE) { kb->i.lspace.flags = kb32->i.lspace.flags; kb->i.lspace.minor = kb32->i.lspace.minor; - memcpy(kb->i.lspace.name, kb32->i.lspace.name, namelen); + memcpy(kb->i.lspace.name, kb32->i.lspace.name, count - + offsetof(struct dlm_write_request32, i.lspace.name)); } else if (kb->cmd == DLM_USER_PURGE) { kb->i.purge.nodeid = kb32->i.purge.nodeid; kb->i.purge.pid = kb32->i.purge.pid; @@ -114,7 +115,8 @@ static void compat_input(struct dlm_write_request *kb, kb->i.lock.bastaddr = (void *)(long)kb32->i.lock.bastaddr; kb->i.lock.lksb = (void *)(long)kb32->i.lock.lksb; memcpy(kb->i.lock.lvb, kb32->i.lock.lvb, DLM_USER_LVB_LEN); - memcpy(kb->i.lock.name, kb32->i.lock.name, namelen); + memcpy(kb->i.lock.name, kb32->i.lock.name, count - + offsetof(struct dlm_write_request32, i.lock.name)); } } @@ -537,16 +539,9 @@ static ssize_t device_write(struct file *file, const char __user *buf, #ifdef CONFIG_COMPAT if (!kbuf->is64bit) { struct dlm_write_request32 *k32buf; - int namelen = 0; - - if (count > sizeof(struct dlm_write_request32)) - namelen = count - sizeof(struct dlm_write_request32); - k32buf = (struct dlm_write_request32 *)kbuf; - - /* add 1 after namelen so that the name string is terminated */ - kbuf = kzalloc(sizeof(struct dlm_write_request) + namelen + 1, - GFP_KERNEL); + kbuf = kmalloc(count + 1 + (sizeof(struct dlm_write_request) - + sizeof(struct dlm_write_request32)), GFP_KERNEL); if (!kbuf) { kfree(k32buf); return -ENOMEM; @@ -554,8 +549,7 @@ static ssize_t device_write(struct file *file, const char __user *buf, if (proc) set_bit(DLM_PROC_FLAGS_COMPAT, &proc->flags); - - compat_input(kbuf, k32buf, namelen); + compat_input(kbuf, k32buf, count + 1); kfree(k32buf); } #endif diff --git a/trunk/fs/quota/dquot.c b/trunk/fs/dquot.c similarity index 85% rename from trunk/fs/quota/dquot.c rename to trunk/fs/dquot.c index 2ca967a5ef77..d6add0bf5ad3 100644 --- a/trunk/fs/quota/dquot.c +++ b/trunk/fs/dquot.c @@ -129,10 +129,9 @@ * i_mutex on quota files is special (it's below dqio_mutex) */ -static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dq_list_lock); -static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dq_state_lock); -__cacheline_aligned_in_smp DEFINE_SPINLOCK(dq_data_lock); -EXPORT_SYMBOL(dq_data_lock); +static DEFINE_SPINLOCK(dq_list_lock); +static DEFINE_SPINLOCK(dq_state_lock); +DEFINE_SPINLOCK(dq_data_lock); static char *quotatypes[] = INITQFNAMES; static struct quota_format_type *quota_formats; /* List of registered formats */ @@ -149,46 +148,35 @@ int register_quota_format(struct quota_format_type *fmt) spin_unlock(&dq_list_lock); return 0; } -EXPORT_SYMBOL(register_quota_format); void unregister_quota_format(struct quota_format_type *fmt) { struct quota_format_type **actqf; spin_lock(&dq_list_lock); - for (actqf = "a_formats; *actqf && *actqf != fmt; - actqf = &(*actqf)->qf_next) - ; + for (actqf = "a_formats; *actqf && *actqf != fmt; actqf = &(*actqf)->qf_next); if (*actqf) *actqf = (*actqf)->qf_next; spin_unlock(&dq_list_lock); } -EXPORT_SYMBOL(unregister_quota_format); static struct quota_format_type *find_quota_format(int id) { struct quota_format_type *actqf; spin_lock(&dq_list_lock); - for (actqf = quota_formats; actqf && actqf->qf_fmt_id != id; - actqf = actqf->qf_next) - ; + for (actqf = quota_formats; actqf && actqf->qf_fmt_id != id; actqf = actqf->qf_next); if (!actqf || !try_module_get(actqf->qf_owner)) { int qm; spin_unlock(&dq_list_lock); - for (qm = 0; module_names[qm].qm_fmt_id && - module_names[qm].qm_fmt_id != id; qm++) - ; - if (!module_names[qm].qm_fmt_id || - request_module(module_names[qm].qm_mod_name)) + for (qm = 0; module_names[qm].qm_fmt_id && module_names[qm].qm_fmt_id != id; qm++); + if (!module_names[qm].qm_fmt_id || request_module(module_names[qm].qm_mod_name)) return NULL; spin_lock(&dq_list_lock); - for (actqf = quota_formats; actqf && actqf->qf_fmt_id != id; - actqf = actqf->qf_next) - ; + for (actqf = quota_formats; actqf && actqf->qf_fmt_id != id; actqf = actqf->qf_next); if (actqf && !try_module_get(actqf->qf_owner)) actqf = NULL; } @@ -227,7 +215,6 @@ static unsigned int dq_hash_bits, dq_hash_mask; static struct hlist_head *dquot_hash; struct dqstats dqstats; -EXPORT_SYMBOL(dqstats); static inline unsigned int hashfn(const struct super_block *sb, unsigned int id, int type) @@ -243,8 +230,7 @@ hashfn(const struct super_block *sb, unsigned int id, int type) */ static inline void insert_dquot_hash(struct dquot *dquot) { - struct hlist_head *head; - head = dquot_hash + hashfn(dquot->dq_sb, dquot->dq_id, dquot->dq_type); + struct hlist_head *head = dquot_hash + hashfn(dquot->dq_sb, dquot->dq_id, dquot->dq_type); hlist_add_head(&dquot->dq_hash, head); } @@ -253,19 +239,17 @@ static inline void remove_dquot_hash(struct dquot *dquot) hlist_del_init(&dquot->dq_hash); } -static struct dquot *find_dquot(unsigned int hashent, struct super_block *sb, - unsigned int id, int type) +static inline struct dquot *find_dquot(unsigned int hashent, struct super_block *sb, unsigned int id, int type) { struct hlist_node *node; struct dquot *dquot; hlist_for_each (node, dquot_hash+hashent) { dquot = hlist_entry(node, struct dquot, dq_hash); - if (dquot->dq_sb == sb && dquot->dq_id == id && - dquot->dq_type == type) + if (dquot->dq_sb == sb && dquot->dq_id == id && dquot->dq_type == type) return dquot; } - return NULL; + return NODQUOT; } /* Add a dquot to the tail of the free list */ @@ -325,7 +309,6 @@ int dquot_mark_dquot_dirty(struct dquot *dquot) spin_unlock(&dq_list_lock); return 0; } -EXPORT_SYMBOL(dquot_mark_dquot_dirty); /* This function needs dq_list_lock */ static inline int clear_dquot_dirty(struct dquot *dquot) @@ -362,10 +345,8 @@ int dquot_acquire(struct dquot *dquot) if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && !dquot->dq_off) { ret = dqopt->ops[dquot->dq_type]->commit_dqblk(dquot); /* Write the info if needed */ - if (info_dirty(&dqopt->info[dquot->dq_type])) { - ret2 = dqopt->ops[dquot->dq_type]->write_file_info( - dquot->dq_sb, dquot->dq_type); - } + if (info_dirty(&dqopt->info[dquot->dq_type])) + ret2 = dqopt->ops[dquot->dq_type]->write_file_info(dquot->dq_sb, dquot->dq_type); if (ret < 0) goto out_iolock; if (ret2 < 0) { @@ -379,7 +360,6 @@ int dquot_acquire(struct dquot *dquot) mutex_unlock(&dquot->dq_lock); return ret; } -EXPORT_SYMBOL(dquot_acquire); /* * Write dquot to disk @@ -400,10 +380,8 @@ int dquot_commit(struct dquot *dquot) * => we have better not writing it */ if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) { ret = dqopt->ops[dquot->dq_type]->commit_dqblk(dquot); - if (info_dirty(&dqopt->info[dquot->dq_type])) { - ret2 = dqopt->ops[dquot->dq_type]->write_file_info( - dquot->dq_sb, dquot->dq_type); - } + if (info_dirty(&dqopt->info[dquot->dq_type])) + ret2 = dqopt->ops[dquot->dq_type]->write_file_info(dquot->dq_sb, dquot->dq_type); if (ret >= 0) ret = ret2; } @@ -411,7 +389,6 @@ int dquot_commit(struct dquot *dquot) mutex_unlock(&dqopt->dqio_mutex); return ret; } -EXPORT_SYMBOL(dquot_commit); /* * Release dquot @@ -429,10 +406,8 @@ int dquot_release(struct dquot *dquot) if (dqopt->ops[dquot->dq_type]->release_dqblk) { ret = dqopt->ops[dquot->dq_type]->release_dqblk(dquot); /* Write the info */ - if (info_dirty(&dqopt->info[dquot->dq_type])) { - ret2 = dqopt->ops[dquot->dq_type]->write_file_info( - dquot->dq_sb, dquot->dq_type); - } + if (info_dirty(&dqopt->info[dquot->dq_type])) + ret2 = dqopt->ops[dquot->dq_type]->write_file_info(dquot->dq_sb, dquot->dq_type); if (ret >= 0) ret = ret2; } @@ -442,7 +417,6 @@ int dquot_release(struct dquot *dquot) mutex_unlock(&dquot->dq_lock); return ret; } -EXPORT_SYMBOL(dquot_release); void dquot_destroy(struct dquot *dquot) { @@ -542,7 +516,6 @@ int dquot_scan_active(struct super_block *sb, mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); return ret; } -EXPORT_SYMBOL(dquot_scan_active); int vfs_quota_sync(struct super_block *sb, int type) { @@ -560,8 +533,7 @@ int vfs_quota_sync(struct super_block *sb, int type) spin_lock(&dq_list_lock); dirty = &dqopt->info[cnt].dqi_dirty_list; while (!list_empty(dirty)) { - dquot = list_first_entry(dirty, struct dquot, - dq_dirty); + dquot = list_first_entry(dirty, struct dquot, dq_dirty); /* Dirty and inactive can be only bad dquot... */ if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) { clear_dquot_dirty(dquot); @@ -591,7 +563,6 @@ int vfs_quota_sync(struct super_block *sb, int type) return 0; } -EXPORT_SYMBOL(vfs_quota_sync); /* Free unused dquots from cache */ static void prune_dqcache(int count) @@ -701,7 +672,6 @@ void dqput(struct dquot *dquot) put_dquot_last(dquot); spin_unlock(&dq_list_lock); } -EXPORT_SYMBOL(dqput); struct dquot *dquot_alloc(struct super_block *sb, int type) { @@ -715,7 +685,7 @@ static struct dquot *get_empty_dquot(struct super_block *sb, int type) dquot = sb->dq_op->alloc_dquot(sb, type); if(!dquot) - return NULL; + return NODQUOT; mutex_init(&dquot->dq_lock); INIT_LIST_HEAD(&dquot->dq_free); @@ -741,10 +711,10 @@ static struct dquot *get_empty_dquot(struct super_block *sb, int type) struct dquot *dqget(struct super_block *sb, unsigned int id, int type) { unsigned int hashent = hashfn(sb, id, type); - struct dquot *dquot = NULL, *empty = NULL; + struct dquot *dquot = NODQUOT, *empty = NODQUOT; if (!sb_has_quota_active(sb, type)) - return NULL; + return NODQUOT; we_slept: spin_lock(&dq_list_lock); spin_lock(&dq_state_lock); @@ -755,17 +725,15 @@ struct dquot *dqget(struct super_block *sb, unsigned int id, int type) } spin_unlock(&dq_state_lock); - dquot = find_dquot(hashent, sb, id, type); - if (!dquot) { - if (!empty) { + if ((dquot = find_dquot(hashent, sb, id, type)) == NODQUOT) { + if (empty == NODQUOT) { spin_unlock(&dq_list_lock); - empty = get_empty_dquot(sb, type); - if (!empty) + if ((empty = get_empty_dquot(sb, type)) == NODQUOT) schedule(); /* Try to wait for a moment... */ goto we_slept; } dquot = empty; - empty = NULL; + empty = NODQUOT; dquot->dq_id = id; /* all dquots go on the inuse_list */ put_inuse(dquot); @@ -781,14 +749,13 @@ struct dquot *dqget(struct super_block *sb, unsigned int id, int type) dqstats.lookups++; spin_unlock(&dq_list_lock); } - /* Wait for dq_lock - after this we know that either dquot_release() is - * already finished or it will be canceled due to dq_count > 1 test */ + /* Wait for dq_lock - after this we know that either dquot_release() is already + * finished or it will be canceled due to dq_count > 1 test */ wait_on_dquot(dquot); - /* Read the dquot / allocate space in quota file */ - if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && - sb->dq_op->acquire_dquot(dquot) < 0) { + /* Read the dquot and instantiate it (everything done only if needed) */ + if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && sb->dq_op->acquire_dquot(dquot) < 0) { dqput(dquot); - dquot = NULL; + dquot = NODQUOT; goto out; } #ifdef __DQUOT_PARANOIA @@ -800,7 +767,6 @@ struct dquot *dqget(struct super_block *sb, unsigned int id, int type) return dquot; } -EXPORT_SYMBOL(dqget); static int dqinit_needed(struct inode *inode, int type) { @@ -809,9 +775,9 @@ static int dqinit_needed(struct inode *inode, int type) if (IS_NOQUOTA(inode)) return 0; if (type != -1) - return !inode->i_dquot[type]; + return inode->i_dquot[type] == NODQUOT; for (cnt = 0; cnt < MAXQUOTAS; cnt++) - if (!inode->i_dquot[cnt]) + if (inode->i_dquot[cnt] == NODQUOT) return 1; return 0; } @@ -823,12 +789,12 @@ static void add_dquot_ref(struct super_block *sb, int type) spin_lock(&inode_lock); list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { - if (inode->i_state & (I_FREEING|I_WILL_FREE|I_NEW)) - continue; if (!atomic_read(&inode->i_writecount)) continue; if (!dqinit_needed(inode, type)) continue; + if (inode->i_state & (I_FREEING|I_WILL_FREE)) + continue; __iget(inode); spin_unlock(&inode_lock); @@ -847,10 +813,7 @@ static void add_dquot_ref(struct super_block *sb, int type) iput(old_inode); } -/* - * Return 0 if dqput() won't block. - * (note that 1 doesn't necessarily mean blocking) - */ +/* Return 0 if dqput() won't block (note that 1 doesn't necessarily mean blocking) */ static inline int dqput_blocks(struct dquot *dquot) { if (atomic_read(&dquot->dq_count) <= 1) @@ -858,27 +821,22 @@ static inline int dqput_blocks(struct dquot *dquot) return 0; } -/* - * Remove references to dquots from inode and add dquot to list for freeing - * if we have the last referece to dquot - * We can't race with anybody because we hold dqptr_sem for writing... - */ +/* Remove references to dquots from inode - add dquot to list for freeing if needed */ +/* We can't race with anybody because we hold dqptr_sem for writing... */ static int remove_inode_dquot_ref(struct inode *inode, int type, struct list_head *tofree_head) { struct dquot *dquot = inode->i_dquot[type]; - inode->i_dquot[type] = NULL; - if (dquot) { + inode->i_dquot[type] = NODQUOT; + if (dquot != NODQUOT) { if (dqput_blocks(dquot)) { #ifdef __DQUOT_PARANOIA if (atomic_read(&dquot->dq_count) != 1) printk(KERN_WARNING "VFS: Adding dquot with dq_count %d to dispose list.\n", atomic_read(&dquot->dq_count)); #endif spin_lock(&dq_list_lock); - /* As dquot must have currently users it can't be on - * the free list... */ - list_add(&dquot->dq_free, tofree_head); + list_add(&dquot->dq_free, tofree_head); /* As dquot must have currently users it can't be on the free list... */ spin_unlock(&dq_list_lock); return 1; } @@ -888,22 +846,19 @@ static int remove_inode_dquot_ref(struct inode *inode, int type, return 0; } -/* - * Free list of dquots - * Dquots are removed from inodes and no new references can be got so we are - * the only ones holding reference - */ +/* Free list of dquots - called from inode.c */ +/* dquots are removed from inodes, no new references can be got so we are the only ones holding reference */ static void put_dquot_list(struct list_head *tofree_head) { struct list_head *act_head; struct dquot *dquot; act_head = tofree_head->next; + /* So now we have dquots on the list... Just free them */ while (act_head != tofree_head) { dquot = list_entry(act_head, struct dquot, dq_free); act_head = act_head->next; - /* Remove dquot from the list so we won't have problems... */ - list_del_init(&dquot->dq_free); + list_del_init(&dquot->dq_free); /* Remove dquot from the list so we won't have problems... */ dqput(dquot); } } @@ -915,12 +870,6 @@ static void remove_dquot_ref(struct super_block *sb, int type, spin_lock(&inode_lock); list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { - /* - * We have to scan also I_NEW inodes because they can already - * have quota pointer initialized. Luckily, we need to touch - * only quota pointers and these have separate locking - * (dqptr_sem). - */ if (!IS_NOQUOTA(inode)) remove_inode_dquot_ref(inode, type, tofree_head); } @@ -950,29 +899,7 @@ static inline void dquot_incr_space(struct dquot *dquot, qsize_t number) dquot->dq_dqb.dqb_curspace += number; } -static inline void dquot_resv_space(struct dquot *dquot, qsize_t number) -{ - dquot->dq_dqb.dqb_rsvspace += number; -} - -/* - * Claim reserved quota space - */ -static void dquot_claim_reserved_space(struct dquot *dquot, - qsize_t number) -{ - WARN_ON(dquot->dq_dqb.dqb_rsvspace < number); - dquot->dq_dqb.dqb_curspace += number; - dquot->dq_dqb.dqb_rsvspace -= number; -} - -static inline -void dquot_free_reserved_space(struct dquot *dquot, qsize_t number) -{ - dquot->dq_dqb.dqb_rsvspace -= number; -} - -static void dquot_decr_inodes(struct dquot *dquot, qsize_t number) +static inline void dquot_decr_inodes(struct dquot *dquot, qsize_t number) { if (sb_dqopt(dquot->dq_sb)->flags & DQUOT_NEGATIVE_USAGE || dquot->dq_dqb.dqb_curinodes >= number) @@ -984,7 +911,7 @@ static void dquot_decr_inodes(struct dquot *dquot, qsize_t number) clear_bit(DQ_INODES_B, &dquot->dq_flags); } -static void dquot_decr_space(struct dquot *dquot, qsize_t number) +static inline void dquot_decr_space(struct dquot *dquot, qsize_t number) { if (sb_dqopt(dquot->dq_sb)->flags & DQUOT_NEGATIVE_USAGE || dquot->dq_dqb.dqb_curspace >= number) @@ -1011,7 +938,7 @@ static int warning_issued(struct dquot *dquot, const int warntype) #ifdef CONFIG_PRINT_QUOTA_WARNING static int flag_print_warnings = 1; -static int need_print_warning(struct dquot *dquot) +static inline int need_print_warning(struct dquot *dquot) { if (!flag_print_warnings) return 0; @@ -1138,17 +1065,13 @@ static void send_warning(const struct dquot *dquot, const char warntype) kfree_skb(skb); } #endif -/* - * Write warnings to the console and send warning messages over netlink. - * - * Note that this function can sleep. - */ -static void flush_warnings(struct dquot *const *dquots, char *warntype) + +static inline void flush_warnings(struct dquot * const *dquots, char *warntype) { int i; for (i = 0; i < MAXQUOTAS; i++) - if (dquots[i] && warntype[i] != QUOTA_NL_NOWARN && + if (dquots[i] != NODQUOT && warntype[i] != QUOTA_NL_NOWARN && !warning_issued(dquots[i], warntype[i])) { #ifdef CONFIG_PRINT_QUOTA_WARNING print_warning(dquots[i], warntype[i]); @@ -1159,47 +1082,42 @@ static void flush_warnings(struct dquot *const *dquots, char *warntype) } } -static int ignore_hardlimit(struct dquot *dquot) +static inline char ignore_hardlimit(struct dquot *dquot) { struct mem_dqinfo *info = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_type]; return capable(CAP_SYS_RESOURCE) && - (info->dqi_format->qf_fmt_id != QFMT_VFS_OLD || - !(info->dqi_flags & V1_DQF_RSQUASH)); + (info->dqi_format->qf_fmt_id != QFMT_VFS_OLD || !(info->dqi_flags & V1_DQF_RSQUASH)); } /* needs dq_data_lock */ static int check_idq(struct dquot *dquot, qsize_t inodes, char *warntype) { - qsize_t newinodes = dquot->dq_dqb.dqb_curinodes + inodes; - *warntype = QUOTA_NL_NOWARN; if (!sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_type) || test_bit(DQ_FAKE_B, &dquot->dq_flags)) return QUOTA_OK; if (dquot->dq_dqb.dqb_ihardlimit && - newinodes > dquot->dq_dqb.dqb_ihardlimit && + (dquot->dq_dqb.dqb_curinodes + inodes) > dquot->dq_dqb.dqb_ihardlimit && !ignore_hardlimit(dquot)) { *warntype = QUOTA_NL_IHARDWARN; return NO_QUOTA; } if (dquot->dq_dqb.dqb_isoftlimit && - newinodes > dquot->dq_dqb.dqb_isoftlimit && - dquot->dq_dqb.dqb_itime && - get_seconds() >= dquot->dq_dqb.dqb_itime && + (dquot->dq_dqb.dqb_curinodes + inodes) > dquot->dq_dqb.dqb_isoftlimit && + dquot->dq_dqb.dqb_itime && get_seconds() >= dquot->dq_dqb.dqb_itime && !ignore_hardlimit(dquot)) { *warntype = QUOTA_NL_ISOFTLONGWARN; return NO_QUOTA; } if (dquot->dq_dqb.dqb_isoftlimit && - newinodes > dquot->dq_dqb.dqb_isoftlimit && + (dquot->dq_dqb.dqb_curinodes + inodes) > dquot->dq_dqb.dqb_isoftlimit && dquot->dq_dqb.dqb_itime == 0) { *warntype = QUOTA_NL_ISOFTWARN; - dquot->dq_dqb.dqb_itime = get_seconds() + - sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_igrace; + dquot->dq_dqb.dqb_itime = get_seconds() + sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_igrace; } return QUOTA_OK; @@ -1208,19 +1126,13 @@ static int check_idq(struct dquot *dquot, qsize_t inodes, char *warntype) /* needs dq_data_lock */ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *warntype) { - qsize_t tspace; - struct super_block *sb = dquot->dq_sb; - *warntype = QUOTA_NL_NOWARN; - if (!sb_has_quota_limits_enabled(sb, dquot->dq_type) || + if (!sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_type) || test_bit(DQ_FAKE_B, &dquot->dq_flags)) return QUOTA_OK; - tspace = dquot->dq_dqb.dqb_curspace + dquot->dq_dqb.dqb_rsvspace - + space; - if (dquot->dq_dqb.dqb_bhardlimit && - tspace > dquot->dq_dqb.dqb_bhardlimit && + dquot->dq_dqb.dqb_curspace + space > dquot->dq_dqb.dqb_bhardlimit && !ignore_hardlimit(dquot)) { if (!prealloc) *warntype = QUOTA_NL_BHARDWARN; @@ -1228,9 +1140,8 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *war } if (dquot->dq_dqb.dqb_bsoftlimit && - tspace > dquot->dq_dqb.dqb_bsoftlimit && - dquot->dq_dqb.dqb_btime && - get_seconds() >= dquot->dq_dqb.dqb_btime && + dquot->dq_dqb.dqb_curspace + space > dquot->dq_dqb.dqb_bsoftlimit && + dquot->dq_dqb.dqb_btime && get_seconds() >= dquot->dq_dqb.dqb_btime && !ignore_hardlimit(dquot)) { if (!prealloc) *warntype = QUOTA_NL_BSOFTLONGWARN; @@ -1238,12 +1149,11 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *war } if (dquot->dq_dqb.dqb_bsoftlimit && - tspace > dquot->dq_dqb.dqb_bsoftlimit && + dquot->dq_dqb.dqb_curspace + space > dquot->dq_dqb.dqb_bsoftlimit && dquot->dq_dqb.dqb_btime == 0) { if (!prealloc) { *warntype = QUOTA_NL_BSOFTWARN; - dquot->dq_dqb.dqb_btime = get_seconds() + - sb_dqopt(sb)->info[dquot->dq_type].dqi_bgrace; + dquot->dq_dqb.dqb_btime = get_seconds() + sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_bgrace; } else /* @@ -1258,18 +1168,15 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *war static int info_idq_free(struct dquot *dquot, qsize_t inodes) { - qsize_t newinodes; - if (test_bit(DQ_FAKE_B, &dquot->dq_flags) || dquot->dq_dqb.dqb_curinodes <= dquot->dq_dqb.dqb_isoftlimit || !sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_type)) return QUOTA_NL_NOWARN; - newinodes = dquot->dq_dqb.dqb_curinodes - inodes; - if (newinodes <= dquot->dq_dqb.dqb_isoftlimit) + if (dquot->dq_dqb.dqb_curinodes - inodes <= dquot->dq_dqb.dqb_isoftlimit) return QUOTA_NL_ISOFTBELOW; if (dquot->dq_dqb.dqb_curinodes >= dquot->dq_dqb.dqb_ihardlimit && - newinodes < dquot->dq_dqb.dqb_ihardlimit) + dquot->dq_dqb.dqb_curinodes - inodes < dquot->dq_dqb.dqb_ihardlimit) return QUOTA_NL_IHARDBELOW; return QUOTA_NL_NOWARN; } @@ -1296,7 +1203,7 @@ int dquot_initialize(struct inode *inode, int type) { unsigned int id = 0; int cnt, ret = 0; - struct dquot *got[MAXQUOTAS] = { NULL, NULL }; + struct dquot *got[MAXQUOTAS] = { NODQUOT, NODQUOT }; struct super_block *sb = inode->i_sb; /* First test before acquiring mutex - solves deadlocks when we @@ -1329,9 +1236,9 @@ int dquot_initialize(struct inode *inode, int type) /* Avoid races with quotaoff() */ if (!sb_has_quota_active(sb, cnt)) continue; - if (!inode->i_dquot[cnt]) { + if (inode->i_dquot[cnt] == NODQUOT) { inode->i_dquot[cnt] = got[cnt]; - got[cnt] = NULL; + got[cnt] = NODQUOT; } } out_err: @@ -1341,7 +1248,6 @@ int dquot_initialize(struct inode *inode, int type) dqput(got[cnt]); return ret; } -EXPORT_SYMBOL(dquot_initialize); /* * Release all quotas referenced by inode @@ -1354,7 +1260,7 @@ int dquot_drop(struct inode *inode) down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); for (cnt = 0; cnt < MAXQUOTAS; cnt++) { put[cnt] = inode->i_dquot[cnt]; - inode->i_dquot[cnt] = NULL; + inode->i_dquot[cnt] = NODQUOT; } up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); @@ -1362,7 +1268,6 @@ int dquot_drop(struct inode *inode) dqput(put[cnt]); return 0; } -EXPORT_SYMBOL(dquot_drop); /* Wrapper to remove references to quota structures from inode */ void vfs_dq_drop(struct inode *inode) @@ -1379,13 +1284,12 @@ void vfs_dq_drop(struct inode *inode) * must assure that nobody can come after the DQUOT_DROP and * add quota pointers back anyway */ for (cnt = 0; cnt < MAXQUOTAS; cnt++) - if (inode->i_dquot[cnt]) + if (inode->i_dquot[cnt] != NODQUOT) break; if (cnt < MAXQUOTAS) inode->i_sb->dq_op->drop(inode); } } -EXPORT_SYMBOL(vfs_dq_drop); /* * Following four functions update i_blocks+i_bytes fields and @@ -1399,93 +1303,51 @@ EXPORT_SYMBOL(vfs_dq_drop); /* * This operation can block, but only after everything is updated */ -int __dquot_alloc_space(struct inode *inode, qsize_t number, - int warn, int reserve) +int dquot_alloc_space(struct inode *inode, qsize_t number, int warn) { - int cnt, ret = QUOTA_OK; + int cnt, ret = NO_QUOTA; char warntype[MAXQUOTAS]; + /* First test before acquiring mutex - solves deadlocks when we + * re-enter the quota code and are already holding the mutex */ + if (IS_NOQUOTA(inode)) { +out_add: + inode_add_bytes(inode, number); + return QUOTA_OK; + } for (cnt = 0; cnt < MAXQUOTAS; cnt++) warntype[cnt] = QUOTA_NL_NOWARN; + down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); + if (IS_NOQUOTA(inode)) { /* Now we can do reliable test... */ + up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); + goto out_add; + } spin_lock(&dq_data_lock); for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - if (!inode->i_dquot[cnt]) + if (inode->i_dquot[cnt] == NODQUOT) continue; - if (check_bdq(inode->i_dquot[cnt], number, warn, warntype+cnt) - == NO_QUOTA) { - ret = NO_QUOTA; - goto out_unlock; - } + if (check_bdq(inode->i_dquot[cnt], number, warn, warntype+cnt) == NO_QUOTA) + goto warn_put_all; } for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - if (!inode->i_dquot[cnt]) + if (inode->i_dquot[cnt] == NODQUOT) continue; - if (reserve) - dquot_resv_space(inode->i_dquot[cnt], number); - else - dquot_incr_space(inode->i_dquot[cnt], number); + dquot_incr_space(inode->i_dquot[cnt], number); } - if (!reserve) - inode_add_bytes(inode, number); -out_unlock: + inode_add_bytes(inode, number); + ret = QUOTA_OK; +warn_put_all: spin_unlock(&dq_data_lock); + if (ret == QUOTA_OK) + /* Dirtify all the dquots - this can block when journalling */ + for (cnt = 0; cnt < MAXQUOTAS; cnt++) + if (inode->i_dquot[cnt]) + mark_dquot_dirty(inode->i_dquot[cnt]); flush_warnings(inode->i_dquot, warntype); - return ret; -} - -int dquot_alloc_space(struct inode *inode, qsize_t number, int warn) -{ - int cnt, ret = QUOTA_OK; - - /* - * First test before acquiring mutex - solves deadlocks when we - * re-enter the quota code and are already holding the mutex - */ - if (IS_NOQUOTA(inode)) { - inode_add_bytes(inode, number); - goto out; - } - - down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); - if (IS_NOQUOTA(inode)) { - inode_add_bytes(inode, number); - goto out_unlock; - } - - ret = __dquot_alloc_space(inode, number, warn, 0); - if (ret == NO_QUOTA) - goto out_unlock; - - /* Dirtify all the dquots - this can block when journalling */ - for (cnt = 0; cnt < MAXQUOTAS; cnt++) - if (inode->i_dquot[cnt]) - mark_dquot_dirty(inode->i_dquot[cnt]); -out_unlock: up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -out: return ret; } -EXPORT_SYMBOL(dquot_alloc_space); - -int dquot_reserve_space(struct inode *inode, qsize_t number, int warn) -{ - int ret = QUOTA_OK; - - if (IS_NOQUOTA(inode)) - goto out; - - down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); - if (IS_NOQUOTA(inode)) - goto out_unlock; - - ret = __dquot_alloc_space(inode, number, warn, 1); -out_unlock: - up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -out: - return ret; -} -EXPORT_SYMBOL(dquot_reserve_space); /* * This operation can block, but only after everything is updated @@ -1508,15 +1370,14 @@ int dquot_alloc_inode(const struct inode *inode, qsize_t number) } spin_lock(&dq_data_lock); for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - if (!inode->i_dquot[cnt]) + if (inode->i_dquot[cnt] == NODQUOT) continue; - if (check_idq(inode->i_dquot[cnt], number, warntype+cnt) - == NO_QUOTA) + if (check_idq(inode->i_dquot[cnt], number, warntype+cnt) == NO_QUOTA) goto warn_put_all; } for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - if (!inode->i_dquot[cnt]) + if (inode->i_dquot[cnt] == NODQUOT) continue; dquot_incr_inodes(inode->i_dquot[cnt], number); } @@ -1532,73 +1393,6 @@ int dquot_alloc_inode(const struct inode *inode, qsize_t number) up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); return ret; } -EXPORT_SYMBOL(dquot_alloc_inode); - -int dquot_claim_space(struct inode *inode, qsize_t number) -{ - int cnt; - int ret = QUOTA_OK; - - if (IS_NOQUOTA(inode)) { - inode_add_bytes(inode, number); - goto out; - } - - down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); - if (IS_NOQUOTA(inode)) { - up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); - inode_add_bytes(inode, number); - goto out; - } - - spin_lock(&dq_data_lock); - /* Claim reserved quotas to allocated quotas */ - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - if (inode->i_dquot[cnt]) - dquot_claim_reserved_space(inode->i_dquot[cnt], - number); - } - /* Update inode bytes */ - inode_add_bytes(inode, number); - spin_unlock(&dq_data_lock); - /* Dirtify all the dquots - this can block when journalling */ - for (cnt = 0; cnt < MAXQUOTAS; cnt++) - if (inode->i_dquot[cnt]) - mark_dquot_dirty(inode->i_dquot[cnt]); - up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -out: - return ret; -} -EXPORT_SYMBOL(dquot_claim_space); - -/* - * Release reserved quota space - */ -void dquot_release_reserved_space(struct inode *inode, qsize_t number) -{ - int cnt; - - if (IS_NOQUOTA(inode)) - goto out; - - down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); - if (IS_NOQUOTA(inode)) - goto out_unlock; - - spin_lock(&dq_data_lock); - /* Release reserved dquots */ - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - if (inode->i_dquot[cnt]) - dquot_free_reserved_space(inode->i_dquot[cnt], number); - } - spin_unlock(&dq_data_lock); - -out_unlock: - up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -out: - return; -} -EXPORT_SYMBOL(dquot_release_reserved_space); /* * This operation can block, but only after everything is updated @@ -1624,7 +1418,7 @@ int dquot_free_space(struct inode *inode, qsize_t number) } spin_lock(&dq_data_lock); for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - if (!inode->i_dquot[cnt]) + if (inode->i_dquot[cnt] == NODQUOT) continue; warntype[cnt] = info_bdq_free(inode->i_dquot[cnt], number); dquot_decr_space(inode->i_dquot[cnt], number); @@ -1639,7 +1433,6 @@ int dquot_free_space(struct inode *inode, qsize_t number) up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); return QUOTA_OK; } -EXPORT_SYMBOL(dquot_free_space); /* * This operation can block, but only after everything is updated @@ -1662,7 +1455,7 @@ int dquot_free_inode(const struct inode *inode, qsize_t number) } spin_lock(&dq_data_lock); for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - if (!inode->i_dquot[cnt]) + if (inode->i_dquot[cnt] == NODQUOT) continue; warntype[cnt] = info_idq_free(inode->i_dquot[cnt], number); dquot_decr_inodes(inode->i_dquot[cnt], number); @@ -1676,20 +1469,6 @@ int dquot_free_inode(const struct inode *inode, qsize_t number) up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); return QUOTA_OK; } -EXPORT_SYMBOL(dquot_free_inode); - -/* - * call back function, get reserved quota space from underlying fs - */ -qsize_t dquot_get_reserved_space(struct inode *inode) -{ - qsize_t reserved_space = 0; - - if (sb_any_quota_active(inode->i_sb) && - inode->i_sb->dq_op->get_reserved_space) - reserved_space = inode->i_sb->dq_op->get_reserved_space(inode); - return reserved_space; -} /* * Transfer the number of inode and blocks from one diskquota to an other. @@ -1699,8 +1478,7 @@ qsize_t dquot_get_reserved_space(struct inode *inode) */ int dquot_transfer(struct inode *inode, struct iattr *iattr) { - qsize_t space, cur_space; - qsize_t rsv_space = 0; + qsize_t space; struct dquot *transfer_from[MAXQUOTAS]; struct dquot *transfer_to[MAXQUOTAS]; int cnt, ret = QUOTA_OK; @@ -1715,16 +1493,22 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr) return QUOTA_OK; /* Initialize the arrays */ for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - transfer_from[cnt] = NULL; - transfer_to[cnt] = NULL; + transfer_from[cnt] = NODQUOT; + transfer_to[cnt] = NODQUOT; warntype_to[cnt] = QUOTA_NL_NOWARN; + switch (cnt) { + case USRQUOTA: + if (!chuid) + continue; + transfer_to[cnt] = dqget(inode->i_sb, iattr->ia_uid, cnt); + break; + case GRPQUOTA: + if (!chgid) + continue; + transfer_to[cnt] = dqget(inode->i_sb, iattr->ia_gid, cnt); + break; + } } - if (chuid) - transfer_to[USRQUOTA] = dqget(inode->i_sb, iattr->ia_uid, - USRQUOTA); - if (chgid) - transfer_to[GRPQUOTA] = dqget(inode->i_sb, iattr->ia_gid, - GRPQUOTA); down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); /* Now recheck reliably when holding dqptr_sem */ @@ -1733,12 +1517,10 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr) goto put_all; } spin_lock(&dq_data_lock); - cur_space = inode_get_bytes(inode); - rsv_space = dquot_get_reserved_space(inode); - space = cur_space + rsv_space; + space = inode_get_bytes(inode); /* Build the transfer_from list and check the limits */ for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - if (!transfer_to[cnt]) + if (transfer_to[cnt] == NODQUOT) continue; transfer_from[cnt] = inode->i_dquot[cnt]; if (check_idq(transfer_to[cnt], 1, warntype_to + cnt) == @@ -1754,7 +1536,7 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr) /* * Skip changes for same uid or gid or for turned off quota-type. */ - if (!transfer_to[cnt]) + if (transfer_to[cnt] == NODQUOT) continue; /* Due to IO error we might not have transfer_from[] structure */ @@ -1764,14 +1546,11 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr) warntype_from_space[cnt] = info_bdq_free(transfer_from[cnt], space); dquot_decr_inodes(transfer_from[cnt], 1); - dquot_decr_space(transfer_from[cnt], cur_space); - dquot_free_reserved_space(transfer_from[cnt], - rsv_space); + dquot_decr_space(transfer_from[cnt], space); } dquot_incr_inodes(transfer_to[cnt], 1); - dquot_incr_space(transfer_to[cnt], cur_space); - dquot_resv_space(transfer_to[cnt], rsv_space); + dquot_incr_space(transfer_to[cnt], space); inode->i_dquot[cnt] = transfer_to[cnt]; } @@ -1785,7 +1564,7 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr) if (transfer_to[cnt]) { mark_dquot_dirty(transfer_to[cnt]); /* The reference we got is transferred to the inode */ - transfer_to[cnt] = NULL; + transfer_to[cnt] = NODQUOT; } } warn_put_all: @@ -1803,11 +1582,10 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr) up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); /* Clear dquot pointers we don't want to dqput() */ for (cnt = 0; cnt < MAXQUOTAS; cnt++) - transfer_from[cnt] = NULL; + transfer_from[cnt] = NODQUOT; ret = NO_QUOTA; goto warn_put_all; } -EXPORT_SYMBOL(dquot_transfer); /* Wrapper for transferring ownership of an inode */ int vfs_dq_transfer(struct inode *inode, struct iattr *iattr) @@ -1819,7 +1597,7 @@ int vfs_dq_transfer(struct inode *inode, struct iattr *iattr) } return 0; } -EXPORT_SYMBOL(vfs_dq_transfer); + /* * Write info of quota file to disk @@ -1834,7 +1612,6 @@ int dquot_commit_info(struct super_block *sb, int type) mutex_unlock(&dqopt->dqio_mutex); return ret; } -EXPORT_SYMBOL(dquot_commit_info); /* * Definitions of diskquota operations. @@ -1920,8 +1697,8 @@ int vfs_quota_disable(struct super_block *sb, int type, unsigned int flags) drop_dquot_ref(sb, cnt); invalidate_dquots(sb, cnt); /* - * Now all dquots should be invalidated, all writes done so we - * should be only users of the info. No locks needed. + * Now all dquots should be invalidated, all writes done so we should be only + * users of the info. No locks needed. */ if (info_dirty(&dqopt->info[cnt])) sb->dq_op->write_info(sb, cnt); @@ -1959,12 +1736,10 @@ int vfs_quota_disable(struct super_block *sb, int type, unsigned int flags) /* If quota was reenabled in the meantime, we have * nothing to do */ if (!sb_has_quota_loaded(sb, cnt)) { - mutex_lock_nested(&toputinode[cnt]->i_mutex, - I_MUTEX_QUOTA); + mutex_lock_nested(&toputinode[cnt]->i_mutex, I_MUTEX_QUOTA); toputinode[cnt]->i_flags &= ~(S_IMMUTABLE | S_NOATIME | S_NOQUOTA); - truncate_inode_pages(&toputinode[cnt]->i_data, - 0); + truncate_inode_pages(&toputinode[cnt]->i_data, 0); mutex_unlock(&toputinode[cnt]->i_mutex); mark_inode_dirty(toputinode[cnt]); } @@ -1989,14 +1764,13 @@ int vfs_quota_disable(struct super_block *sb, int type, unsigned int flags) } return ret; } -EXPORT_SYMBOL(vfs_quota_disable); int vfs_quota_off(struct super_block *sb, int type, int remount) { return vfs_quota_disable(sb, type, remount ? DQUOT_SUSPENDED : (DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED)); } -EXPORT_SYMBOL(vfs_quota_off); + /* * Turn quotas on on a device */ @@ -2054,8 +1828,7 @@ static int vfs_load_quota_inode(struct inode *inode, int type, int format_id, * possible) Also nobody should write to the file - we use * special IO operations which ignore the immutable bit. */ down_write(&dqopt->dqptr_sem); - oldflags = inode->i_flags & (S_NOATIME | S_IMMUTABLE | - S_NOQUOTA); + oldflags = inode->i_flags & (S_NOATIME | S_IMMUTABLE | S_NOQUOTA); inode->i_flags |= S_NOQUOTA | S_NOATIME | S_IMMUTABLE; up_write(&dqopt->dqptr_sem); sb->dq_op->drop(inode); @@ -2074,8 +1847,7 @@ static int vfs_load_quota_inode(struct inode *inode, int type, int format_id, dqopt->info[type].dqi_fmt_id = format_id; INIT_LIST_HEAD(&dqopt->info[type].dqi_dirty_list); mutex_lock(&dqopt->dqio_mutex); - error = dqopt->ops[type]->read_file_info(sb, type); - if (error < 0) { + if ((error = dqopt->ops[type]->read_file_info(sb, type)) < 0) { mutex_unlock(&dqopt->dqio_mutex); goto out_file_init; } @@ -2155,7 +1927,6 @@ int vfs_quota_on_path(struct super_block *sb, int type, int format_id, DQUOT_LIMITS_ENABLED); return error; } -EXPORT_SYMBOL(vfs_quota_on_path); int vfs_quota_on(struct super_block *sb, int type, int format_id, char *name, int remount) @@ -2173,7 +1944,6 @@ int vfs_quota_on(struct super_block *sb, int type, int format_id, char *name, } return error; } -EXPORT_SYMBOL(vfs_quota_on); /* * More powerful function for turning on quotas allowing setting @@ -2220,7 +1990,6 @@ int vfs_quota_enable(struct inode *inode, int type, int format_id, load_quota: return vfs_load_quota_inode(inode, type, format_id, flags); } -EXPORT_SYMBOL(vfs_quota_enable); /* * This function is used when filesystem needs to initialize quotas @@ -2250,7 +2019,6 @@ int vfs_quota_on_mount(struct super_block *sb, char *qf_name, dput(dentry); return error; } -EXPORT_SYMBOL(vfs_quota_on_mount); /* Wrapper to turn on quotas when remounting rw */ int vfs_dq_quota_on_remount(struct super_block *sb) @@ -2267,7 +2035,6 @@ int vfs_dq_quota_on_remount(struct super_block *sb) } return ret; } -EXPORT_SYMBOL(vfs_dq_quota_on_remount); static inline qsize_t qbtos(qsize_t blocks) { @@ -2287,7 +2054,7 @@ static void do_get_dqblk(struct dquot *dquot, struct if_dqblk *di) spin_lock(&dq_data_lock); di->dqb_bhardlimit = stoqb(dm->dqb_bhardlimit); di->dqb_bsoftlimit = stoqb(dm->dqb_bsoftlimit); - di->dqb_curspace = dm->dqb_curspace + dm->dqb_rsvspace; + di->dqb_curspace = dm->dqb_curspace; di->dqb_ihardlimit = dm->dqb_ihardlimit; di->dqb_isoftlimit = dm->dqb_isoftlimit; di->dqb_curinodes = dm->dqb_curinodes; @@ -2297,20 +2064,18 @@ static void do_get_dqblk(struct dquot *dquot, struct if_dqblk *di) spin_unlock(&dq_data_lock); } -int vfs_get_dqblk(struct super_block *sb, int type, qid_t id, - struct if_dqblk *di) +int vfs_get_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di) { struct dquot *dquot; dquot = dqget(sb, id, type); - if (!dquot) + if (dquot == NODQUOT) return -ESRCH; do_get_dqblk(dquot, di); dqput(dquot); return 0; } -EXPORT_SYMBOL(vfs_get_dqblk); /* Generic routine for setting common part of quota structure */ static int do_set_dqblk(struct dquot *dquot, struct if_dqblk *di) @@ -2329,7 +2094,7 @@ static int do_set_dqblk(struct dquot *dquot, struct if_dqblk *di) spin_lock(&dq_data_lock); if (di->dqb_valid & QIF_SPACE) { - dm->dqb_curspace = di->dqb_curspace - dm->dqb_rsvspace; + dm->dqb_curspace = di->dqb_curspace; check_blim = 1; __set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags); } @@ -2362,25 +2127,22 @@ static int do_set_dqblk(struct dquot *dquot, struct if_dqblk *di) } if (check_blim) { - if (!dm->dqb_bsoftlimit || - dm->dqb_curspace < dm->dqb_bsoftlimit) { + if (!dm->dqb_bsoftlimit || dm->dqb_curspace < dm->dqb_bsoftlimit) { dm->dqb_btime = 0; clear_bit(DQ_BLKS_B, &dquot->dq_flags); - } else if (!(di->dqb_valid & QIF_BTIME)) - /* Set grace only if user hasn't provided his own... */ + } + else if (!(di->dqb_valid & QIF_BTIME)) /* Set grace only if user hasn't provided his own... */ dm->dqb_btime = get_seconds() + dqi->dqi_bgrace; } if (check_ilim) { - if (!dm->dqb_isoftlimit || - dm->dqb_curinodes < dm->dqb_isoftlimit) { + if (!dm->dqb_isoftlimit || dm->dqb_curinodes < dm->dqb_isoftlimit) { dm->dqb_itime = 0; clear_bit(DQ_INODES_B, &dquot->dq_flags); - } else if (!(di->dqb_valid & QIF_ITIME)) - /* Set grace only if user hasn't provided his own... */ + } + else if (!(di->dqb_valid & QIF_ITIME)) /* Set grace only if user hasn't provided his own... */ dm->dqb_itime = get_seconds() + dqi->dqi_igrace; } - if (dm->dqb_bhardlimit || dm->dqb_bsoftlimit || dm->dqb_ihardlimit || - dm->dqb_isoftlimit) + if (dm->dqb_bhardlimit || dm->dqb_bsoftlimit || dm->dqb_ihardlimit || dm->dqb_isoftlimit) clear_bit(DQ_FAKE_B, &dquot->dq_flags); else set_bit(DQ_FAKE_B, &dquot->dq_flags); @@ -2390,8 +2152,7 @@ static int do_set_dqblk(struct dquot *dquot, struct if_dqblk *di) return 0; } -int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, - struct if_dqblk *di) +int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di) { struct dquot *dquot; int rc; @@ -2406,7 +2167,6 @@ int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, out: return rc; } -EXPORT_SYMBOL(vfs_set_dqblk); /* Generic routine for getting common part of quota file information */ int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) @@ -2428,7 +2188,6 @@ int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); return 0; } -EXPORT_SYMBOL(vfs_get_dqinfo); /* Generic routine for setting common part of quota file information */ int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) @@ -2448,8 +2207,7 @@ int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) if (ii->dqi_valid & IIF_IGRACE) mi->dqi_igrace = ii->dqi_igrace; if (ii->dqi_valid & IIF_FLAGS) - mi->dqi_flags = (mi->dqi_flags & ~DQF_MASK) | - (ii->dqi_flags & DQF_MASK); + mi->dqi_flags = (mi->dqi_flags & ~DQF_MASK) | (ii->dqi_flags & DQF_MASK); spin_unlock(&dq_data_lock); mark_info_dirty(sb, type); /* Force write to disk */ @@ -2458,7 +2216,6 @@ int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); return err; } -EXPORT_SYMBOL(vfs_set_dqinfo); struct quotactl_ops vfs_quotactl_ops = { .quota_on = vfs_quota_on, @@ -2608,10 +2365,43 @@ static int __init dquot_init(void) #ifdef CONFIG_QUOTA_NETLINK_INTERFACE if (genl_register_family("a_genl_family) != 0) - printk(KERN_ERR - "VFS: Failed to create quota netlink interface.\n"); + printk(KERN_ERR "VFS: Failed to create quota netlink interface.\n"); #endif return 0; } module_init(dquot_init); + +EXPORT_SYMBOL(register_quota_format); +EXPORT_SYMBOL(unregister_quota_format); +EXPORT_SYMBOL(dqstats); +EXPORT_SYMBOL(dq_data_lock); +EXPORT_SYMBOL(vfs_quota_enable); +EXPORT_SYMBOL(vfs_quota_on); +EXPORT_SYMBOL(vfs_quota_on_path); +EXPORT_SYMBOL(vfs_quota_on_mount); +EXPORT_SYMBOL(vfs_quota_disable); +EXPORT_SYMBOL(vfs_quota_off); +EXPORT_SYMBOL(dquot_scan_active); +EXPORT_SYMBOL(vfs_quota_sync); +EXPORT_SYMBOL(vfs_get_dqinfo); +EXPORT_SYMBOL(vfs_set_dqinfo); +EXPORT_SYMBOL(vfs_get_dqblk); +EXPORT_SYMBOL(vfs_set_dqblk); +EXPORT_SYMBOL(dquot_commit); +EXPORT_SYMBOL(dquot_commit_info); +EXPORT_SYMBOL(dquot_acquire); +EXPORT_SYMBOL(dquot_release); +EXPORT_SYMBOL(dquot_mark_dquot_dirty); +EXPORT_SYMBOL(dquot_initialize); +EXPORT_SYMBOL(dquot_drop); +EXPORT_SYMBOL(vfs_dq_drop); +EXPORT_SYMBOL(dqget); +EXPORT_SYMBOL(dqput); +EXPORT_SYMBOL(dquot_alloc_space); +EXPORT_SYMBOL(dquot_alloc_inode); +EXPORT_SYMBOL(dquot_free_space); +EXPORT_SYMBOL(dquot_free_inode); +EXPORT_SYMBOL(dquot_transfer); +EXPORT_SYMBOL(vfs_dq_transfer); +EXPORT_SYMBOL(vfs_dq_quota_on_remount); diff --git a/trunk/fs/drop_caches.c b/trunk/fs/drop_caches.c index 44d725f612cf..3e5637fc3779 100644 --- a/trunk/fs/drop_caches.c +++ b/trunk/fs/drop_caches.c @@ -18,7 +18,7 @@ static void drop_pagecache_sb(struct super_block *sb) spin_lock(&inode_lock); list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { - if (inode->i_state & (I_FREEING|I_WILL_FREE|I_NEW)) + if (inode->i_state & (I_FREEING|I_WILL_FREE)) continue; if (inode->i_mapping->nrpages == 0) continue; diff --git a/trunk/fs/ecryptfs/dentry.c b/trunk/fs/ecryptfs/dentry.c index 2dda5ade75bc..5e596583946c 100644 --- a/trunk/fs/ecryptfs/dentry.c +++ b/trunk/fs/ecryptfs/dentry.c @@ -89,7 +89,7 @@ static void ecryptfs_d_release(struct dentry *dentry) return; } -const struct dentry_operations ecryptfs_dops = { +struct dentry_operations ecryptfs_dops = { .d_revalidate = ecryptfs_d_revalidate, .d_release = ecryptfs_d_release, }; diff --git a/trunk/fs/ecryptfs/ecryptfs_kernel.h b/trunk/fs/ecryptfs/ecryptfs_kernel.h index 064c5820e4e5..ac749d4d644f 100644 --- a/trunk/fs/ecryptfs/ecryptfs_kernel.h +++ b/trunk/fs/ecryptfs/ecryptfs_kernel.h @@ -580,7 +580,7 @@ extern const struct inode_operations ecryptfs_main_iops; extern const struct inode_operations ecryptfs_dir_iops; extern const struct inode_operations ecryptfs_symlink_iops; extern const struct super_operations ecryptfs_sops; -extern const struct dentry_operations ecryptfs_dops; +extern struct dentry_operations ecryptfs_dops; extern struct address_space_operations ecryptfs_aops; extern int ecryptfs_verbosity; extern unsigned int ecryptfs_message_buf_len; diff --git a/trunk/fs/ext2/balloc.c b/trunk/fs/ext2/balloc.c index 7f8d2e5a7ea6..4a29d6376081 100644 --- a/trunk/fs/ext2/balloc.c +++ b/trunk/fs/ext2/balloc.c @@ -570,7 +570,7 @@ void ext2_free_blocks (struct inode * inode, unsigned long block, error_return: brelse(bitmap_bh); release_blocks(sb, freed); - vfs_dq_free_block(inode, freed); + DQUOT_FREE_BLOCK(inode, freed); } /** @@ -1247,7 +1247,7 @@ ext2_fsblk_t ext2_new_blocks(struct inode *inode, ext2_fsblk_t goal, /* * Check quota for allocation of this block. */ - if (vfs_dq_alloc_block(inode, num)) { + if (DQUOT_ALLOC_BLOCK(inode, num)) { *errp = -EDQUOT; return 0; } @@ -1409,7 +1409,7 @@ ext2_fsblk_t ext2_new_blocks(struct inode *inode, ext2_fsblk_t goal, *errp = 0; brelse(bitmap_bh); - vfs_dq_free_block(inode, *count-num); + DQUOT_FREE_BLOCK(inode, *count-num); *count = num; return ret_block; @@ -1420,7 +1420,7 @@ ext2_fsblk_t ext2_new_blocks(struct inode *inode, ext2_fsblk_t goal, * Undo the block allocation */ if (!performed_allocation) - vfs_dq_free_block(inode, *count); + DQUOT_FREE_BLOCK(inode, *count); brelse(bitmap_bh); return 0; } diff --git a/trunk/fs/ext2/ialloc.c b/trunk/fs/ext2/ialloc.c index 15387c9c17d8..66321a877e74 100644 --- a/trunk/fs/ext2/ialloc.c +++ b/trunk/fs/ext2/ialloc.c @@ -121,8 +121,8 @@ void ext2_free_inode (struct inode * inode) if (!is_bad_inode(inode)) { /* Quota is already initialized in iput() */ ext2_xattr_delete_inode(inode); - vfs_dq_free_inode(inode); - vfs_dq_drop(inode); + DQUOT_FREE_INODE(inode); + DQUOT_DROP(inode); } es = EXT2_SB(sb)->s_es; @@ -586,7 +586,7 @@ struct inode *ext2_new_inode(struct inode *dir, int mode) goto fail_drop; } - if (vfs_dq_alloc_inode(inode)) { + if (DQUOT_ALLOC_INODE(inode)) { err = -EDQUOT; goto fail_drop; } @@ -605,10 +605,10 @@ struct inode *ext2_new_inode(struct inode *dir, int mode) return inode; fail_free_drop: - vfs_dq_free_inode(inode); + DQUOT_FREE_INODE(inode); fail_drop: - vfs_dq_drop(inode); + DQUOT_DROP(inode); inode->i_flags |= S_NOQUOTA; inode->i_nlink = 0; unlock_new_inode(inode); diff --git a/trunk/fs/ext2/inode.c b/trunk/fs/ext2/inode.c index b43b95563663..23fff2f87783 100644 --- a/trunk/fs/ext2/inode.c +++ b/trunk/fs/ext2/inode.c @@ -1444,7 +1444,7 @@ int ext2_setattr(struct dentry *dentry, struct iattr *iattr) return error; if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) || (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) { - error = vfs_dq_transfer(inode, iattr) ? -EDQUOT : 0; + error = DQUOT_TRANSFER(inode, iattr) ? -EDQUOT : 0; if (error) return error; } diff --git a/trunk/fs/ext2/super.c b/trunk/fs/ext2/super.c index f983225266dc..7c6e3606f0ec 100644 --- a/trunk/fs/ext2/super.c +++ b/trunk/fs/ext2/super.c @@ -1331,7 +1331,6 @@ static ssize_t ext2_quota_read(struct super_block *sb, int type, char *data, sb->s_blocksize - offset : toread; tmp_bh.b_state = 0; - tmp_bh.b_size = sb->s_blocksize; err = ext2_get_block(inode, blk, &tmp_bh, 0); if (err < 0) return err; diff --git a/trunk/fs/ext2/xattr.c b/trunk/fs/ext2/xattr.c index 7913531ec6d5..987a5261cc2e 100644 --- a/trunk/fs/ext2/xattr.c +++ b/trunk/fs/ext2/xattr.c @@ -642,7 +642,7 @@ ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh, ea_bdebug(new_bh, "reusing block"); error = -EDQUOT; - if (vfs_dq_alloc_block(inode, 1)) { + if (DQUOT_ALLOC_BLOCK(inode, 1)) { unlock_buffer(new_bh); goto cleanup; } @@ -699,7 +699,7 @@ ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh, * as if nothing happened and cleanup the unused block */ if (error && error != -ENOSPC) { if (new_bh && new_bh != old_bh) - vfs_dq_free_block(inode, 1); + DQUOT_FREE_BLOCK(inode, 1); goto cleanup; } } else @@ -731,7 +731,7 @@ ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh, le32_add_cpu(&HDR(old_bh)->h_refcount, -1); if (ce) mb_cache_entry_release(ce); - vfs_dq_free_block(inode, 1); + DQUOT_FREE_BLOCK(inode, 1); mark_buffer_dirty(old_bh); ea_bdebug(old_bh, "refcount now=%d", le32_to_cpu(HDR(old_bh)->h_refcount)); @@ -794,7 +794,7 @@ ext2_xattr_delete_inode(struct inode *inode) mark_buffer_dirty(bh); if (IS_SYNC(inode)) sync_dirty_buffer(bh); - vfs_dq_free_block(inode, 1); + DQUOT_FREE_BLOCK(inode, 1); } EXT2_I(inode)->i_file_acl = 0; diff --git a/trunk/fs/ext3/balloc.c b/trunk/fs/ext3/balloc.c index 225202db8974..0dbf1c048475 100644 --- a/trunk/fs/ext3/balloc.c +++ b/trunk/fs/ext3/balloc.c @@ -676,7 +676,7 @@ void ext3_free_blocks(handle_t *handle, struct inode *inode, } ext3_free_blocks_sb(handle, sb, block, count, &dquot_freed_blocks); if (dquot_freed_blocks) - vfs_dq_free_block(inode, dquot_freed_blocks); + DQUOT_FREE_BLOCK(inode, dquot_freed_blocks); return; } @@ -1502,7 +1502,7 @@ ext3_fsblk_t ext3_new_blocks(handle_t *handle, struct inode *inode, /* * Check quota for allocation of this block. */ - if (vfs_dq_alloc_block(inode, num)) { + if (DQUOT_ALLOC_BLOCK(inode, num)) { *errp = -EDQUOT; return 0; } @@ -1714,7 +1714,7 @@ ext3_fsblk_t ext3_new_blocks(handle_t *handle, struct inode *inode, *errp = 0; brelse(bitmap_bh); - vfs_dq_free_block(inode, *count-num); + DQUOT_FREE_BLOCK(inode, *count-num); *count = num; return ret_block; @@ -1729,7 +1729,7 @@ ext3_fsblk_t ext3_new_blocks(handle_t *handle, struct inode *inode, * Undo the block allocation */ if (!performed_allocation) - vfs_dq_free_block(inode, *count); + DQUOT_FREE_BLOCK(inode, *count); brelse(bitmap_bh); return 0; } diff --git a/trunk/fs/ext3/ialloc.c b/trunk/fs/ext3/ialloc.c index dd13d60d524b..8de6c720e510 100644 --- a/trunk/fs/ext3/ialloc.c +++ b/trunk/fs/ext3/ialloc.c @@ -123,10 +123,10 @@ void ext3_free_inode (handle_t *handle, struct inode * inode) * Note: we must free any quota before locking the superblock, * as writing the quota to disk may need the lock as well. */ - vfs_dq_init(inode); + DQUOT_INIT(inode); ext3_xattr_delete_inode(handle, inode); - vfs_dq_free_inode(inode); - vfs_dq_drop(inode); + DQUOT_FREE_INODE(inode); + DQUOT_DROP(inode); is_directory = S_ISDIR(inode->i_mode); @@ -589,7 +589,7 @@ struct inode *ext3_new_inode(handle_t *handle, struct inode * dir, int mode) sizeof(struct ext3_inode) - EXT3_GOOD_OLD_INODE_SIZE : 0; ret = inode; - if (vfs_dq_alloc_inode(inode)) { + if(DQUOT_ALLOC_INODE(inode)) { err = -EDQUOT; goto fail_drop; } @@ -620,10 +620,10 @@ struct inode *ext3_new_inode(handle_t *handle, struct inode * dir, int mode) return ret; fail_free_drop: - vfs_dq_free_inode(inode); + DQUOT_FREE_INODE(inode); fail_drop: - vfs_dq_drop(inode); + DQUOT_DROP(inode); inode->i_flags |= S_NOQUOTA; inode->i_nlink = 0; unlock_new_inode(inode); diff --git a/trunk/fs/ext3/inode.c b/trunk/fs/ext3/inode.c index 4a09ff169870..05e5c2e5c0d7 100644 --- a/trunk/fs/ext3/inode.c +++ b/trunk/fs/ext3/inode.c @@ -3063,7 +3063,7 @@ int ext3_setattr(struct dentry *dentry, struct iattr *attr) error = PTR_ERR(handle); goto err_out; } - error = vfs_dq_transfer(inode, attr) ? -EDQUOT : 0; + error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0; if (error) { ext3_journal_stop(handle); return error; @@ -3154,7 +3154,7 @@ static int ext3_writepage_trans_blocks(struct inode *inode) ret = 2 * (bpp + indirects) + 2; #ifdef CONFIG_QUOTA - /* We know that structure was already allocated during vfs_dq_init so + /* We know that structure was already allocated during DQUOT_INIT so * we will be updating only the data blocks + inodes */ ret += 2*EXT3_QUOTA_TRANS_BLOCKS(inode->i_sb); #endif @@ -3245,7 +3245,7 @@ int ext3_mark_inode_dirty(handle_t *handle, struct inode *inode) * i_size has been changed by generic_commit_write() and we thus need * to include the updated inode in the current transaction. * - * Also, vfs_dq_alloc_space() will always dirty the inode when blocks + * Also, DQUOT_ALLOC_SPACE() will always dirty the inode when blocks * are allocated to the file. * * If the inode is marked synchronous, we don't honour that here - doing diff --git a/trunk/fs/ext3/namei.c b/trunk/fs/ext3/namei.c index e2fc63cbba8b..4db4ffa1edad 100644 --- a/trunk/fs/ext3/namei.c +++ b/trunk/fs/ext3/namei.c @@ -2049,7 +2049,7 @@ static int ext3_rmdir (struct inode * dir, struct dentry *dentry) /* Initialize quotas before so that eventual writes go in * separate transaction */ - vfs_dq_init(dentry->d_inode); + DQUOT_INIT(dentry->d_inode); handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS(dir->i_sb)); if (IS_ERR(handle)) return PTR_ERR(handle); @@ -2108,7 +2108,7 @@ static int ext3_unlink(struct inode * dir, struct dentry *dentry) /* Initialize quotas before so that eventual writes go * in separate transaction */ - vfs_dq_init(dentry->d_inode); + DQUOT_INIT(dentry->d_inode); handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS(dir->i_sb)); if (IS_ERR(handle)) return PTR_ERR(handle); @@ -2272,7 +2272,7 @@ static int ext3_rename (struct inode * old_dir, struct dentry *old_dentry, /* Initialize quotas before so that eventual writes go * in separate transaction */ if (new_dentry->d_inode) - vfs_dq_init(new_dentry->d_inode); + DQUOT_INIT(new_dentry->d_inode); handle = ext3_journal_start(old_dir, 2 * EXT3_DATA_TRANS_BLOCKS(old_dir->i_sb) + EXT3_INDEX_EXTRA_TRANS_BLOCKS + 2); diff --git a/trunk/fs/ext3/super.c b/trunk/fs/ext3/super.c index 9e5b8e387e1e..4a970411a458 100644 --- a/trunk/fs/ext3/super.c +++ b/trunk/fs/ext3/super.c @@ -707,6 +707,8 @@ static int bdev_try_to_free_page(struct super_block *sb, struct page *page, #define QTYPE2NAME(t) ((t)==USRQUOTA?"user":"group") #define QTYPE2MOPT(on, t) ((t)==USRQUOTA?((on)##USRJQUOTA):((on)##GRPJQUOTA)) +static int ext3_dquot_initialize(struct inode *inode, int type); +static int ext3_dquot_drop(struct inode *inode); static int ext3_write_dquot(struct dquot *dquot); static int ext3_acquire_dquot(struct dquot *dquot); static int ext3_release_dquot(struct dquot *dquot); @@ -721,8 +723,8 @@ static ssize_t ext3_quota_write(struct super_block *sb, int type, const char *data, size_t len, loff_t off); static struct dquot_operations ext3_quota_operations = { - .initialize = dquot_initialize, - .drop = dquot_drop, + .initialize = ext3_dquot_initialize, + .drop = ext3_dquot_drop, .alloc_space = dquot_alloc_space, .alloc_inode = dquot_alloc_inode, .free_space = dquot_free_space, @@ -1436,7 +1438,7 @@ static void ext3_orphan_cleanup (struct super_block * sb, } list_add(&EXT3_I(inode)->i_orphan, &EXT3_SB(sb)->s_orphan); - vfs_dq_init(inode); + DQUOT_INIT(inode); if (inode->i_nlink) { printk(KERN_DEBUG "%s: truncating inode %lu to %Ld bytes\n", @@ -2700,7 +2702,7 @@ static int ext3_statfs (struct dentry * dentry, struct kstatfs * buf) * Process 1 Process 2 * ext3_create() quota_sync() * journal_start() write_dquot() - * vfs_dq_init() down(dqio_mutex) + * DQUOT_INIT() down(dqio_mutex) * down(dqio_mutex) journal_start() * */ @@ -2712,6 +2714,44 @@ static inline struct inode *dquot_to_inode(struct dquot *dquot) return sb_dqopt(dquot->dq_sb)->files[dquot->dq_type]; } +static int ext3_dquot_initialize(struct inode *inode, int type) +{ + handle_t *handle; + int ret, err; + + /* We may create quota structure so we need to reserve enough blocks */ + handle = ext3_journal_start(inode, 2*EXT3_QUOTA_INIT_BLOCKS(inode->i_sb)); + if (IS_ERR(handle)) + return PTR_ERR(handle); + ret = dquot_initialize(inode, type); + err = ext3_journal_stop(handle); + if (!ret) + ret = err; + return ret; +} + +static int ext3_dquot_drop(struct inode *inode) +{ + handle_t *handle; + int ret, err; + + /* We may delete quota structure so we need to reserve enough blocks */ + handle = ext3_journal_start(inode, 2*EXT3_QUOTA_DEL_BLOCKS(inode->i_sb)); + if (IS_ERR(handle)) { + /* + * We call dquot_drop() anyway to at least release references + * to quota structures so that umount does not hang. + */ + dquot_drop(inode); + return PTR_ERR(handle); + } + ret = dquot_drop(inode); + err = ext3_journal_stop(handle); + if (!ret) + ret = err; + return ret; +} + static int ext3_write_dquot(struct dquot *dquot) { int ret, err; diff --git a/trunk/fs/ext3/xattr.c b/trunk/fs/ext3/xattr.c index 83b7be849bd5..175414ac2210 100644 --- a/trunk/fs/ext3/xattr.c +++ b/trunk/fs/ext3/xattr.c @@ -498,7 +498,7 @@ ext3_xattr_release_block(handle_t *handle, struct inode *inode, error = ext3_journal_dirty_metadata(handle, bh); if (IS_SYNC(inode)) handle->h_sync = 1; - vfs_dq_free_block(inode, 1); + DQUOT_FREE_BLOCK(inode, 1); ea_bdebug(bh, "refcount now=%d; releasing", le32_to_cpu(BHDR(bh)->h_refcount)); if (ce) @@ -774,7 +774,7 @@ ext3_xattr_block_set(handle_t *handle, struct inode *inode, /* The old block is released after updating the inode. */ error = -EDQUOT; - if (vfs_dq_alloc_block(inode, 1)) + if (DQUOT_ALLOC_BLOCK(inode, 1)) goto cleanup; error = ext3_journal_get_write_access(handle, new_bh); @@ -848,7 +848,7 @@ ext3_xattr_block_set(handle_t *handle, struct inode *inode, return error; cleanup_dquot: - vfs_dq_free_block(inode, 1); + DQUOT_FREE_BLOCK(inode, 1); goto cleanup; bad_block: diff --git a/trunk/fs/ext4/balloc.c b/trunk/fs/ext4/balloc.c index 38f40d55899c..de9459b4cb94 100644 --- a/trunk/fs/ext4/balloc.c +++ b/trunk/fs/ext4/balloc.c @@ -536,7 +536,7 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode, ext4_mb_free_blocks(handle, inode, block, count, metadata, &dquot_freed_blocks); if (dquot_freed_blocks) - vfs_dq_free_block(inode, dquot_freed_blocks); + DQUOT_FREE_BLOCK(inode, dquot_freed_blocks); return; } diff --git a/trunk/fs/ext4/ext4.h b/trunk/fs/ext4/ext4.h index 6083bb38057b..b0c87dce66a3 100644 --- a/trunk/fs/ext4/ext4.h +++ b/trunk/fs/ext4/ext4.h @@ -20,7 +20,6 @@ #include #include #include -#include #include "ext4_i.h" /* @@ -1099,7 +1098,6 @@ extern int ext4_chunk_trans_blocks(struct inode *, int nrblocks); extern int ext4_block_truncate_page(handle_t *handle, struct address_space *mapping, loff_t from); extern int ext4_page_mkwrite(struct vm_area_struct *vma, struct page *page); -extern qsize_t ext4_get_reserved_space(struct inode *inode); /* ioctl.c */ extern long ext4_ioctl(struct file *, unsigned int, unsigned long); diff --git a/trunk/fs/ext4/ialloc.c b/trunk/fs/ext4/ialloc.c index fb51b40e3e8f..2d2b3585ee91 100644 --- a/trunk/fs/ext4/ialloc.c +++ b/trunk/fs/ext4/ialloc.c @@ -220,10 +220,10 @@ void ext4_free_inode(handle_t *handle, struct inode *inode) * Note: we must free any quota before locking the superblock, * as writing the quota to disk may need the lock as well. */ - vfs_dq_init(inode); + DQUOT_INIT(inode); ext4_xattr_delete_inode(handle, inode); - vfs_dq_free_inode(inode); - vfs_dq_drop(inode); + DQUOT_FREE_INODE(inode); + DQUOT_DROP(inode); is_directory = S_ISDIR(inode->i_mode); @@ -915,7 +915,7 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode) ei->i_extra_isize = EXT4_SB(sb)->s_want_extra_isize; ret = inode; - if (vfs_dq_alloc_inode(inode)) { + if (DQUOT_ALLOC_INODE(inode)) { err = -EDQUOT; goto fail_drop; } @@ -956,10 +956,10 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode) return ret; fail_free_drop: - vfs_dq_free_inode(inode); + DQUOT_FREE_INODE(inode); fail_drop: - vfs_dq_drop(inode); + DQUOT_DROP(inode); inode->i_flags |= S_NOQUOTA; inode->i_nlink = 0; unlock_new_inode(inode); diff --git a/trunk/fs/ext4/inode.c b/trunk/fs/ext4/inode.c index 71d3ecd5db79..c7fed5b18745 100644 --- a/trunk/fs/ext4/inode.c +++ b/trunk/fs/ext4/inode.c @@ -975,17 +975,6 @@ static int ext4_get_blocks_handle(handle_t *handle, struct inode *inode, return err; } -qsize_t ext4_get_reserved_space(struct inode *inode) -{ - unsigned long long total; - - spin_lock(&EXT4_I(inode)->i_block_reservation_lock); - total = EXT4_I(inode)->i_reserved_data_blocks + - EXT4_I(inode)->i_reserved_meta_blocks; - spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); - - return total; -} /* * Calculate the number of metadata blocks need to reserve * to allocate @blocks for non extent file based file @@ -1047,14 +1036,8 @@ static void ext4_da_update_reserve_space(struct inode *inode, int used) /* update per-inode reservations */ BUG_ON(used > EXT4_I(inode)->i_reserved_data_blocks); EXT4_I(inode)->i_reserved_data_blocks -= used; - spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); - - /* - * free those over-booking quota for metadata blocks - */ - if (mdb_free) - vfs_dq_release_reservation_block(inode, mdb_free); + spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); } /* @@ -1570,8 +1553,8 @@ static int ext4_journalled_write_end(struct file *file, static int ext4_da_reserve_space(struct inode *inode, int nrblocks) { int retries = 0; - struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); - unsigned long md_needed, mdblocks, total = 0; + struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); + unsigned long md_needed, mdblocks, total = 0; /* * recalculate the amount of metadata blocks to reserve @@ -1587,23 +1570,12 @@ static int ext4_da_reserve_space(struct inode *inode, int nrblocks) md_needed = mdblocks - EXT4_I(inode)->i_reserved_meta_blocks; total = md_needed + nrblocks; - /* - * Make quota reservation here to prevent quota overflow - * later. Real quota accounting is done at pages writeout - * time. - */ - if (vfs_dq_reserve_block(inode, total)) { - spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); - return -EDQUOT; - } - if (ext4_claim_free_blocks(sbi, total)) { spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); if (ext4_should_retry_alloc(inode->i_sb, &retries)) { yield(); goto repeat; } - vfs_dq_release_reservation_block(inode, total); return -ENOSPC; } EXT4_I(inode)->i_reserved_data_blocks += nrblocks; @@ -1657,8 +1629,6 @@ static void ext4_da_release_space(struct inode *inode, int to_free) BUG_ON(mdb > EXT4_I(inode)->i_reserved_meta_blocks); EXT4_I(inode)->i_reserved_meta_blocks = mdb; spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); - - vfs_dq_release_reservation_block(inode, release); } static void ext4_da_page_release_reservation(struct page *page, @@ -4642,7 +4612,7 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr) error = PTR_ERR(handle); goto err_out; } - error = vfs_dq_transfer(inode, attr) ? -EDQUOT : 0; + error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0; if (error) { ext4_journal_stop(handle); return error; @@ -5021,7 +4991,7 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode) * i_size has been changed by generic_commit_write() and we thus need * to include the updated inode in the current transaction. * - * Also, vfs_dq_alloc_block() will always dirty the inode when blocks + * Also, DQUOT_ALLOC_SPACE() will always dirty the inode when blocks * are allocated to the file. * * If the inode is marked synchronous, we don't honour that here - doing diff --git a/trunk/fs/ext4/mballoc.c b/trunk/fs/ext4/mballoc.c index b038188bd039..9f61e62f435f 100644 --- a/trunk/fs/ext4/mballoc.c +++ b/trunk/fs/ext4/mballoc.c @@ -3086,12 +3086,9 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac, if (!(ac->ac_flags & EXT4_MB_DELALLOC_RESERVED)) /* release all the reserved blocks if non delalloc */ percpu_counter_sub(&sbi->s_dirtyblocks_counter, reserv_blks); - else { + else percpu_counter_sub(&sbi->s_dirtyblocks_counter, ac->ac_b_ex.fe_len); - /* convert reserved quota blocks to real quota blocks */ - vfs_dq_claim_block(ac->ac_inode, ac->ac_b_ex.fe_len); - } if (sbi->s_log_groups_per_flex) { ext4_group_t flex_group = ext4_flex_group(sbi, @@ -4547,7 +4544,7 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle, struct ext4_sb_info *sbi; struct super_block *sb; ext4_fsblk_t block = 0; - unsigned int inquota = 0; + unsigned int inquota; unsigned int reserv_blks = 0; sb = ar->inode->i_sb; @@ -4565,17 +4562,9 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle, (unsigned long long) ar->pleft, (unsigned long long) ar->pright); - /* - * For delayed allocation, we could skip the ENOSPC and - * EDQUOT check, as blocks and quotas have been already - * reserved when data being copied into pagecache. - */ - if (EXT4_I(ar->inode)->i_delalloc_reserved_flag) - ar->flags |= EXT4_MB_DELALLOC_RESERVED; - else { - /* Without delayed allocation we need to verify - * there is enough free blocks to do block allocation - * and verify allocation doesn't exceed the quota limits. + if (!EXT4_I(ar->inode)->i_delalloc_reserved_flag) { + /* + * With delalloc we already reserved the blocks */ while (ar->len && ext4_claim_free_blocks(sbi, ar->len)) { /* let others to free the space */ @@ -4587,16 +4576,19 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle, return 0; } reserv_blks = ar->len; - while (ar->len && vfs_dq_alloc_block(ar->inode, ar->len)) { - ar->flags |= EXT4_MB_HINT_NOPREALLOC; - ar->len--; - } - inquota = ar->len; - if (ar->len == 0) { - *errp = -EDQUOT; - goto out3; - } } + while (ar->len && DQUOT_ALLOC_BLOCK(ar->inode, ar->len)) { + ar->flags |= EXT4_MB_HINT_NOPREALLOC; + ar->len--; + } + if (ar->len == 0) { + *errp = -EDQUOT; + goto out3; + } + inquota = ar->len; + + if (EXT4_I(ar->inode)->i_delalloc_reserved_flag) + ar->flags |= EXT4_MB_DELALLOC_RESERVED; ac = kmem_cache_alloc(ext4_ac_cachep, GFP_NOFS); if (!ac) { @@ -4662,8 +4654,8 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle, out2: kmem_cache_free(ext4_ac_cachep, ac); out1: - if (inquota && ar->len < inquota) - vfs_dq_free_block(ar->inode, inquota - ar->len); + if (ar->len < inquota) + DQUOT_FREE_BLOCK(ar->inode, inquota - ar->len); out3: if (!ar->len) { if (!EXT4_I(ar->inode)->i_delalloc_reserved_flag) diff --git a/trunk/fs/ext4/namei.c b/trunk/fs/ext4/namei.c index 83410244d3ee..ba702bd7910d 100644 --- a/trunk/fs/ext4/namei.c +++ b/trunk/fs/ext4/namei.c @@ -2092,7 +2092,7 @@ static int ext4_rmdir(struct inode *dir, struct dentry *dentry) /* Initialize quotas before so that eventual writes go in * separate transaction */ - vfs_dq_init(dentry->d_inode); + DQUOT_INIT(dentry->d_inode); handle = ext4_journal_start(dir, EXT4_DELETE_TRANS_BLOCKS(dir->i_sb)); if (IS_ERR(handle)) return PTR_ERR(handle); @@ -2151,7 +2151,7 @@ static int ext4_unlink(struct inode *dir, struct dentry *dentry) /* Initialize quotas before so that eventual writes go * in separate transaction */ - vfs_dq_init(dentry->d_inode); + DQUOT_INIT(dentry->d_inode); handle = ext4_journal_start(dir, EXT4_DELETE_TRANS_BLOCKS(dir->i_sb)); if (IS_ERR(handle)) return PTR_ERR(handle); @@ -2318,7 +2318,7 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry, /* Initialize quotas before so that eventual writes go * in separate transaction */ if (new_dentry->d_inode) - vfs_dq_init(new_dentry->d_inode); + DQUOT_INIT(new_dentry->d_inode); handle = ext4_journal_start(old_dir, 2 * EXT4_DATA_TRANS_BLOCKS(old_dir->i_sb) + EXT4_INDEX_EXTRA_TRANS_BLOCKS + 2); diff --git a/trunk/fs/ext4/super.c b/trunk/fs/ext4/super.c index f7371a6a923d..39d1993cfa13 100644 --- a/trunk/fs/ext4/super.c +++ b/trunk/fs/ext4/super.c @@ -926,6 +926,8 @@ static int bdev_try_to_free_page(struct super_block *sb, struct page *page, gfp_ #define QTYPE2NAME(t) ((t) == USRQUOTA ? "user" : "group") #define QTYPE2MOPT(on, t) ((t) == USRQUOTA?((on)##USRJQUOTA):((on)##GRPJQUOTA)) +static int ext4_dquot_initialize(struct inode *inode, int type); +static int ext4_dquot_drop(struct inode *inode); static int ext4_write_dquot(struct dquot *dquot); static int ext4_acquire_dquot(struct dquot *dquot); static int ext4_release_dquot(struct dquot *dquot); @@ -940,13 +942,9 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type, const char *data, size_t len, loff_t off); static struct dquot_operations ext4_quota_operations = { - .initialize = dquot_initialize, - .drop = dquot_drop, + .initialize = ext4_dquot_initialize, + .drop = ext4_dquot_drop, .alloc_space = dquot_alloc_space, - .reserve_space = dquot_reserve_space, - .claim_space = dquot_claim_space, - .release_rsv = dquot_release_reserved_space, - .get_reserved_space = ext4_get_reserved_space, .alloc_inode = dquot_alloc_inode, .free_space = dquot_free_space, .free_inode = dquot_free_inode, @@ -1804,7 +1802,7 @@ static void ext4_orphan_cleanup(struct super_block *sb, } list_add(&EXT4_I(inode)->i_orphan, &EXT4_SB(sb)->s_orphan); - vfs_dq_init(inode); + DQUOT_INIT(inode); if (inode->i_nlink) { printk(KERN_DEBUG "%s: truncating inode %lu to %lld bytes\n", @@ -3369,8 +3367,8 @@ static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf) * is locked for write. Otherwise the are possible deadlocks: * Process 1 Process 2 * ext4_create() quota_sync() - * jbd2_journal_start() write_dquot() - * vfs_dq_init() down(dqio_mutex) + * jbd2_journal_start() write_dquot() + * DQUOT_INIT() down(dqio_mutex) * down(dqio_mutex) jbd2_journal_start() * */ @@ -3382,6 +3380,44 @@ static inline struct inode *dquot_to_inode(struct dquot *dquot) return sb_dqopt(dquot->dq_sb)->files[dquot->dq_type]; } +static int ext4_dquot_initialize(struct inode *inode, int type) +{ + handle_t *handle; + int ret, err; + + /* We may create quota structure so we need to reserve enough blocks */ + handle = ext4_journal_start(inode, 2*EXT4_QUOTA_INIT_BLOCKS(inode->i_sb)); + if (IS_ERR(handle)) + return PTR_ERR(handle); + ret = dquot_initialize(inode, type); + err = ext4_journal_stop(handle); + if (!ret) + ret = err; + return ret; +} + +static int ext4_dquot_drop(struct inode *inode) +{ + handle_t *handle; + int ret, err; + + /* We may delete quota structure so we need to reserve enough blocks */ + handle = ext4_journal_start(inode, 2*EXT4_QUOTA_DEL_BLOCKS(inode->i_sb)); + if (IS_ERR(handle)) { + /* + * We call dquot_drop() anyway to at least release references + * to quota structures so that umount does not hang. + */ + dquot_drop(inode); + return PTR_ERR(handle); + } + ret = dquot_drop(inode); + err = ext4_journal_stop(handle); + if (!ret) + ret = err; + return ret; +} + static int ext4_write_dquot(struct dquot *dquot) { int ret, err; diff --git a/trunk/fs/ext4/xattr.c b/trunk/fs/ext4/xattr.c index 62b31c246994..157ce6589c54 100644 --- a/trunk/fs/ext4/xattr.c +++ b/trunk/fs/ext4/xattr.c @@ -490,7 +490,7 @@ ext4_xattr_release_block(handle_t *handle, struct inode *inode, error = ext4_handle_dirty_metadata(handle, inode, bh); if (IS_SYNC(inode)) ext4_handle_sync(handle); - vfs_dq_free_block(inode, 1); + DQUOT_FREE_BLOCK(inode, 1); ea_bdebug(bh, "refcount now=%d; releasing", le32_to_cpu(BHDR(bh)->h_refcount)); if (ce) @@ -784,7 +784,7 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode, /* The old block is released after updating the inode. */ error = -EDQUOT; - if (vfs_dq_alloc_block(inode, 1)) + if (DQUOT_ALLOC_BLOCK(inode, 1)) goto cleanup; error = ext4_journal_get_write_access(handle, new_bh); @@ -860,7 +860,7 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode, return error; cleanup_dquot: - vfs_dq_free_block(inode, 1); + DQUOT_FREE_BLOCK(inode, 1); goto cleanup; bad_block: diff --git a/trunk/fs/fat/namei_msdos.c b/trunk/fs/fat/namei_msdos.c index da3f361a37dd..7ba03a4acbe0 100644 --- a/trunk/fs/fat/namei_msdos.c +++ b/trunk/fs/fat/namei_msdos.c @@ -188,7 +188,7 @@ static int msdos_cmp(struct dentry *dentry, struct qstr *a, struct qstr *b) goto out; } -static const struct dentry_operations msdos_dentry_operations = { +static struct dentry_operations msdos_dentry_operations = { .d_hash = msdos_hash, .d_compare = msdos_cmp, }; diff --git a/trunk/fs/fat/namei_vfat.c b/trunk/fs/fat/namei_vfat.c index a0e00e3a46e9..8ae32e37673c 100644 --- a/trunk/fs/fat/namei_vfat.c +++ b/trunk/fs/fat/namei_vfat.c @@ -166,13 +166,13 @@ static int vfat_cmp(struct dentry *dentry, struct qstr *a, struct qstr *b) return 1; } -static const struct dentry_operations vfat_ci_dentry_ops = { +static struct dentry_operations vfat_ci_dentry_ops = { .d_revalidate = vfat_revalidate_ci, .d_hash = vfat_hashi, .d_compare = vfat_cmpi, }; -static const struct dentry_operations vfat_dentry_ops = { +static struct dentry_operations vfat_dentry_ops = { .d_revalidate = vfat_revalidate, .d_hash = vfat_hash, .d_compare = vfat_cmp, diff --git a/trunk/fs/fuse/dir.c b/trunk/fs/fuse/dir.c index 06da05261e04..fdff346e96fd 100644 --- a/trunk/fs/fuse/dir.c +++ b/trunk/fs/fuse/dir.c @@ -224,7 +224,7 @@ static int invalid_nodeid(u64 nodeid) return !nodeid || nodeid == FUSE_ROOT_ID; } -const struct dentry_operations fuse_dentry_operations = { +struct dentry_operations fuse_dentry_operations = { .d_revalidate = fuse_dentry_revalidate, }; diff --git a/trunk/fs/fuse/fuse_i.h b/trunk/fs/fuse/fuse_i.h index 6fc5aedaa0d5..5e64b815a5a1 100644 --- a/trunk/fs/fuse/fuse_i.h +++ b/trunk/fs/fuse/fuse_i.h @@ -493,7 +493,7 @@ static inline u64 get_node_id(struct inode *inode) /** Device operations */ extern const struct file_operations fuse_dev_operations; -extern const struct dentry_operations fuse_dentry_operations; +extern struct dentry_operations fuse_dentry_operations; /** * Get a filled in inode diff --git a/trunk/fs/gfs2/ops_dentry.c b/trunk/fs/gfs2/ops_dentry.c index 022c66cd5606..5eb57b044382 100644 --- a/trunk/fs/gfs2/ops_dentry.c +++ b/trunk/fs/gfs2/ops_dentry.c @@ -107,7 +107,7 @@ static int gfs2_dhash(struct dentry *dentry, struct qstr *str) return 0; } -const struct dentry_operations gfs2_dops = { +struct dentry_operations gfs2_dops = { .d_revalidate = gfs2_drevalidate, .d_hash = gfs2_dhash, }; diff --git a/trunk/fs/gfs2/super.h b/trunk/fs/gfs2/super.h index b56413e3e40d..91abdbedcc86 100644 --- a/trunk/fs/gfs2/super.h +++ b/trunk/fs/gfs2/super.h @@ -49,7 +49,7 @@ extern struct file_system_type gfs2_fs_type; extern struct file_system_type gfs2meta_fs_type; extern const struct export_operations gfs2_export_ops; extern const struct super_operations gfs2_super_ops; -extern const struct dentry_operations gfs2_dops; +extern struct dentry_operations gfs2_dops; #endif /* __SUPER_DOT_H__ */ diff --git a/trunk/fs/hfs/hfs_fs.h b/trunk/fs/hfs/hfs_fs.h index 052387e11671..9955232fdf8c 100644 --- a/trunk/fs/hfs/hfs_fs.h +++ b/trunk/fs/hfs/hfs_fs.h @@ -213,7 +213,7 @@ extern void hfs_mdb_put(struct super_block *); extern int hfs_part_find(struct super_block *, sector_t *, sector_t *); /* string.c */ -extern const struct dentry_operations hfs_dentry_operations; +extern struct dentry_operations hfs_dentry_operations; extern int hfs_hash_dentry(struct dentry *, struct qstr *); extern int hfs_strcmp(const unsigned char *, unsigned int, diff --git a/trunk/fs/hfs/sysdep.c b/trunk/fs/hfs/sysdep.c index 7478f5c219aa..5bf89ec01cd4 100644 --- a/trunk/fs/hfs/sysdep.c +++ b/trunk/fs/hfs/sysdep.c @@ -31,7 +31,7 @@ static int hfs_revalidate_dentry(struct dentry *dentry, struct nameidata *nd) return 1; } -const struct dentry_operations hfs_dentry_operations = +struct dentry_operations hfs_dentry_operations = { .d_revalidate = hfs_revalidate_dentry, .d_hash = hfs_hash_dentry, diff --git a/trunk/fs/hfsplus/hfsplus_fs.h b/trunk/fs/hfsplus/hfsplus_fs.h index 5c10d803d9df..f027a905225f 100644 --- a/trunk/fs/hfsplus/hfsplus_fs.h +++ b/trunk/fs/hfsplus/hfsplus_fs.h @@ -327,7 +327,7 @@ void hfsplus_file_truncate(struct inode *); /* inode.c */ extern const struct address_space_operations hfsplus_aops; extern const struct address_space_operations hfsplus_btree_aops; -extern const struct dentry_operations hfsplus_dentry_operations; +extern struct dentry_operations hfsplus_dentry_operations; void hfsplus_inode_read_fork(struct inode *, struct hfsplus_fork_raw *); void hfsplus_inode_write_fork(struct inode *, struct hfsplus_fork_raw *); diff --git a/trunk/fs/hfsplus/inode.c b/trunk/fs/hfsplus/inode.c index 1bcf597c0562..f105ee9e1cc4 100644 --- a/trunk/fs/hfsplus/inode.c +++ b/trunk/fs/hfsplus/inode.c @@ -137,7 +137,7 @@ const struct address_space_operations hfsplus_aops = { .writepages = hfsplus_writepages, }; -const struct dentry_operations hfsplus_dentry_operations = { +struct dentry_operations hfsplus_dentry_operations = { .d_hash = hfsplus_hash_dentry, .d_compare = hfsplus_compare_dentry, }; diff --git a/trunk/fs/hostfs/hostfs_kern.c b/trunk/fs/hostfs/hostfs_kern.c index fe02ad4740e7..5c538e0ec14b 100644 --- a/trunk/fs/hostfs/hostfs_kern.c +++ b/trunk/fs/hostfs/hostfs_kern.c @@ -31,12 +31,12 @@ static inline struct hostfs_inode_info *HOSTFS_I(struct inode *inode) #define FILE_HOSTFS_I(file) HOSTFS_I((file)->f_path.dentry->d_inode) -static int hostfs_d_delete(struct dentry *dentry) +int hostfs_d_delete(struct dentry *dentry) { return 1; } -static const struct dentry_operations hostfs_dentry_ops = { +struct dentry_operations hostfs_dentry_ops = { .d_delete = hostfs_d_delete, }; diff --git a/trunk/fs/hpfs/dentry.c b/trunk/fs/hpfs/dentry.c index 940d6d150bee..08319126b2af 100644 --- a/trunk/fs/hpfs/dentry.c +++ b/trunk/fs/hpfs/dentry.c @@ -49,7 +49,7 @@ static int hpfs_compare_dentry(struct dentry *dentry, struct qstr *a, struct qst return 0; } -static const struct dentry_operations hpfs_dentry_operations = { +static struct dentry_operations hpfs_dentry_operations = { .d_hash = hpfs_hash_dentry, .d_compare = hpfs_compare_dentry, }; diff --git a/trunk/fs/inode.c b/trunk/fs/inode.c index d06d6d268de9..643ac43e5a5c 100644 --- a/trunk/fs/inode.c +++ b/trunk/fs/inode.c @@ -294,7 +294,7 @@ void clear_inode(struct inode *inode) BUG_ON(!(inode->i_state & I_FREEING)); BUG_ON(inode->i_state & I_CLEAR); inode_sync_wait(inode); - vfs_dq_drop(inode); + DQUOT_DROP(inode); if (inode->i_sb->s_op->clear_inode) inode->i_sb->s_op->clear_inode(inode); if (S_ISBLK(inode->i_mode) && inode->i_bdev) @@ -366,8 +366,6 @@ static int invalidate_list(struct list_head *head, struct list_head *dispose) if (tmp == head) break; inode = list_entry(tmp, struct inode, i_sb_list); - if (inode->i_state & I_NEW) - continue; invalidate_inode_buffers(inode); if (!atomic_read(&inode->i_count)) { list_move(&inode->i_list, dispose); @@ -1170,7 +1168,7 @@ void generic_delete_inode(struct inode *inode) if (op->delete_inode) { void (*delete)(struct inode *) = op->delete_inode; if (!is_bad_inode(inode)) - vfs_dq_init(inode); + DQUOT_INIT(inode); /* Filesystems implementing their own * s_op->delete_inode are required to call * truncate_inode_pages and clear_inode() diff --git a/trunk/fs/isofs/inode.c b/trunk/fs/isofs/inode.c index 13d2eddd0692..6147ec3643a0 100644 --- a/trunk/fs/isofs/inode.c +++ b/trunk/fs/isofs/inode.c @@ -114,7 +114,7 @@ static const struct super_operations isofs_sops = { }; -static const struct dentry_operations isofs_dentry_ops[] = { +static struct dentry_operations isofs_dentry_ops[] = { { .d_hash = isofs_hash, .d_compare = isofs_dentry_cmp, diff --git a/trunk/fs/jfs/acl.c b/trunk/fs/jfs/acl.c index a166c1669e82..d3e5c33665de 100644 --- a/trunk/fs/jfs/acl.c +++ b/trunk/fs/jfs/acl.c @@ -233,7 +233,7 @@ int jfs_setattr(struct dentry *dentry, struct iattr *iattr) if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) || (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) { - if (vfs_dq_transfer(inode, iattr)) + if (DQUOT_TRANSFER(inode, iattr)) return -EDQUOT; } diff --git a/trunk/fs/jfs/inode.c b/trunk/fs/jfs/inode.c index b2ae190a77ba..b00ee9f05a06 100644 --- a/trunk/fs/jfs/inode.c +++ b/trunk/fs/jfs/inode.c @@ -158,9 +158,9 @@ void jfs_delete_inode(struct inode *inode) /* * Free the inode from the quota allocation. */ - vfs_dq_init(inode); - vfs_dq_free_inode(inode); - vfs_dq_drop(inode); + DQUOT_INIT(inode); + DQUOT_FREE_INODE(inode); + DQUOT_DROP(inode); } clear_inode(inode); diff --git a/trunk/fs/jfs/jfs_dtree.c b/trunk/fs/jfs/jfs_dtree.c index 925871e9887b..4dcc05819998 100644 --- a/trunk/fs/jfs/jfs_dtree.c +++ b/trunk/fs/jfs/jfs_dtree.c @@ -381,10 +381,10 @@ static u32 add_index(tid_t tid, struct inode *ip, s64 bn, int slot) * It's time to move the inline table to an external * page and begin to build the xtree */ - if (vfs_dq_alloc_block(ip, sbi->nbperpage)) + if (DQUOT_ALLOC_BLOCK(ip, sbi->nbperpage)) goto clean_up; if (dbAlloc(ip, 0, sbi->nbperpage, &xaddr)) { - vfs_dq_free_block(ip, sbi->nbperpage); + DQUOT_FREE_BLOCK(ip, sbi->nbperpage); goto clean_up; } @@ -408,7 +408,7 @@ static u32 add_index(tid_t tid, struct inode *ip, s64 bn, int slot) memcpy(&jfs_ip->i_dirtable, temp_table, sizeof (temp_table)); dbFree(ip, xaddr, sbi->nbperpage); - vfs_dq_free_block(ip, sbi->nbperpage); + DQUOT_FREE_BLOCK(ip, sbi->nbperpage); goto clean_up; } ip->i_size = PSIZE; @@ -1027,7 +1027,7 @@ static int dtSplitUp(tid_t tid, n = xlen; /* Allocate blocks to quota. */ - if (vfs_dq_alloc_block(ip, n)) { + if (DQUOT_ALLOC_BLOCK(ip, n)) { rc = -EDQUOT; goto extendOut; } @@ -1308,7 +1308,7 @@ static int dtSplitUp(tid_t tid, /* Rollback quota allocation */ if (rc && quota_allocation) - vfs_dq_free_block(ip, quota_allocation); + DQUOT_FREE_BLOCK(ip, quota_allocation); dtSplitUp_Exit: @@ -1369,7 +1369,7 @@ static int dtSplitPage(tid_t tid, struct inode *ip, struct dtsplit * split, return -EIO; /* Allocate blocks to quota. */ - if (vfs_dq_alloc_block(ip, lengthPXD(pxd))) { + if (DQUOT_ALLOC_BLOCK(ip, lengthPXD(pxd))) { release_metapage(rmp); return -EDQUOT; } @@ -1916,7 +1916,7 @@ static int dtSplitRoot(tid_t tid, rp = rmp->data; /* Allocate blocks to quota. */ - if (vfs_dq_alloc_block(ip, lengthPXD(pxd))) { + if (DQUOT_ALLOC_BLOCK(ip, lengthPXD(pxd))) { release_metapage(rmp); return -EDQUOT; } @@ -2287,7 +2287,7 @@ static int dtDeleteUp(tid_t tid, struct inode *ip, xlen = lengthPXD(&fp->header.self); /* Free quota allocation. */ - vfs_dq_free_block(ip, xlen); + DQUOT_FREE_BLOCK(ip, xlen); /* free/invalidate its buffer page */ discard_metapage(fmp); @@ -2363,7 +2363,7 @@ static int dtDeleteUp(tid_t tid, struct inode *ip, xlen = lengthPXD(&p->header.self); /* Free quota allocation */ - vfs_dq_free_block(ip, xlen); + DQUOT_FREE_BLOCK(ip, xlen); /* free/invalidate its buffer page */ discard_metapage(mp); diff --git a/trunk/fs/jfs/jfs_extent.c b/trunk/fs/jfs/jfs_extent.c index 169802ea07f9..7ae1e3281de9 100644 --- a/trunk/fs/jfs/jfs_extent.c +++ b/trunk/fs/jfs/jfs_extent.c @@ -141,7 +141,7 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, bool abnr) } /* Allocate blocks to quota. */ - if (vfs_dq_alloc_block(ip, nxlen)) { + if (DQUOT_ALLOC_BLOCK(ip, nxlen)) { dbFree(ip, nxaddr, (s64) nxlen); mutex_unlock(&JFS_IP(ip)->commit_mutex); return -EDQUOT; @@ -164,7 +164,7 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, bool abnr) */ if (rc) { dbFree(ip, nxaddr, nxlen); - vfs_dq_free_block(ip, nxlen); + DQUOT_FREE_BLOCK(ip, nxlen); mutex_unlock(&JFS_IP(ip)->commit_mutex); return (rc); } @@ -256,7 +256,7 @@ int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, bool abnr) goto exit; /* Allocat blocks to quota. */ - if (vfs_dq_alloc_block(ip, nxlen)) { + if (DQUOT_ALLOC_BLOCK(ip, nxlen)) { dbFree(ip, nxaddr, (s64) nxlen); mutex_unlock(&JFS_IP(ip)->commit_mutex); return -EDQUOT; @@ -297,7 +297,7 @@ int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, bool abnr) /* extend the extent */ if ((rc = xtExtend(0, ip, xoff + xlen, (int) nextend, 0))) { dbFree(ip, xaddr + xlen, delta); - vfs_dq_free_block(ip, nxlen); + DQUOT_FREE_BLOCK(ip, nxlen); goto exit; } } else { @@ -308,7 +308,7 @@ int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, bool abnr) */ if ((rc = xtTailgate(0, ip, xoff, (int) ntail, nxaddr, 0))) { dbFree(ip, nxaddr, nxlen); - vfs_dq_free_block(ip, nxlen); + DQUOT_FREE_BLOCK(ip, nxlen); goto exit; } } diff --git a/trunk/fs/jfs/jfs_inode.c b/trunk/fs/jfs/jfs_inode.c index dc0e02159ac9..d4d142c2edd4 100644 --- a/trunk/fs/jfs/jfs_inode.c +++ b/trunk/fs/jfs/jfs_inode.c @@ -116,7 +116,7 @@ struct inode *ialloc(struct inode *parent, umode_t mode) /* * Allocate inode to quota. */ - if (vfs_dq_alloc_inode(inode)) { + if (DQUOT_ALLOC_INODE(inode)) { rc = -EDQUOT; goto fail_drop; } @@ -162,7 +162,7 @@ struct inode *ialloc(struct inode *parent, umode_t mode) return inode; fail_drop: - vfs_dq_drop(inode); + DQUOT_DROP(inode); inode->i_flags |= S_NOQUOTA; fail_unlock: inode->i_nlink = 0; diff --git a/trunk/fs/jfs/jfs_inode.h b/trunk/fs/jfs/jfs_inode.h index 1eff7db34d63..adb2fafcc544 100644 --- a/trunk/fs/jfs/jfs_inode.h +++ b/trunk/fs/jfs/jfs_inode.h @@ -47,5 +47,5 @@ extern const struct file_operations jfs_dir_operations; extern const struct inode_operations jfs_file_inode_operations; extern const struct file_operations jfs_file_operations; extern const struct inode_operations jfs_symlink_inode_operations; -extern const struct dentry_operations jfs_ci_dentry_operations; +extern struct dentry_operations jfs_ci_dentry_operations; #endif /* _H_JFS_INODE */ diff --git a/trunk/fs/jfs/jfs_xtree.c b/trunk/fs/jfs/jfs_xtree.c index a27e26c90568..ae3acafb447b 100644 --- a/trunk/fs/jfs/jfs_xtree.c +++ b/trunk/fs/jfs/jfs_xtree.c @@ -846,10 +846,10 @@ int xtInsert(tid_t tid, /* transaction id */ hint = addressXAD(xad) + lengthXAD(xad) - 1; } else hint = 0; - if ((rc = vfs_dq_alloc_block(ip, xlen))) + if ((rc = DQUOT_ALLOC_BLOCK(ip, xlen))) goto out; if ((rc = dbAlloc(ip, hint, (s64) xlen, &xaddr))) { - vfs_dq_free_block(ip, xlen); + DQUOT_FREE_BLOCK(ip, xlen); goto out; } } @@ -878,7 +878,7 @@ int xtInsert(tid_t tid, /* transaction id */ /* undo data extent allocation */ if (*xaddrp == 0) { dbFree(ip, xaddr, (s64) xlen); - vfs_dq_free_block(ip, xlen); + DQUOT_FREE_BLOCK(ip, xlen); } return rc; } @@ -1246,7 +1246,7 @@ xtSplitPage(tid_t tid, struct inode *ip, rbn = addressPXD(pxd); /* Allocate blocks to quota. */ - if (vfs_dq_alloc_block(ip, lengthPXD(pxd))) { + if (DQUOT_ALLOC_BLOCK(ip, lengthPXD(pxd))) { rc = -EDQUOT; goto clean_up; } @@ -1456,7 +1456,7 @@ xtSplitPage(tid_t tid, struct inode *ip, /* Rollback quota allocation. */ if (quota_allocation) - vfs_dq_free_block(ip, quota_allocation); + DQUOT_FREE_BLOCK(ip, quota_allocation); return (rc); } @@ -1513,7 +1513,7 @@ xtSplitRoot(tid_t tid, return -EIO; /* Allocate blocks to quota. */ - if (vfs_dq_alloc_block(ip, lengthPXD(pxd))) { + if (DQUOT_ALLOC_BLOCK(ip, lengthPXD(pxd))) { release_metapage(rmp); return -EDQUOT; } @@ -3941,7 +3941,7 @@ s64 xtTruncate(tid_t tid, struct inode *ip, s64 newsize, int flag) ip->i_size = newsize; /* update quota allocation to reflect freed blocks */ - vfs_dq_free_block(ip, nfreed); + DQUOT_FREE_BLOCK(ip, nfreed); /* * free tlock of invalidated pages diff --git a/trunk/fs/jfs/namei.c b/trunk/fs/jfs/namei.c index 514ee2edb92a..b4de56b851e4 100644 --- a/trunk/fs/jfs/namei.c +++ b/trunk/fs/jfs/namei.c @@ -35,7 +35,7 @@ /* * forward references */ -const struct dentry_operations jfs_ci_dentry_operations; +struct dentry_operations jfs_ci_dentry_operations; static s64 commitZeroLink(tid_t, struct inode *); @@ -356,7 +356,7 @@ static int jfs_rmdir(struct inode *dip, struct dentry *dentry) jfs_info("jfs_rmdir: dip:0x%p name:%s", dip, dentry->d_name.name); /* Init inode for quota operations. */ - vfs_dq_init(ip); + DQUOT_INIT(ip); /* directory must be empty to be removed */ if (!dtEmpty(ip)) { @@ -483,7 +483,7 @@ static int jfs_unlink(struct inode *dip, struct dentry *dentry) jfs_info("jfs_unlink: dip:0x%p name:%s", dip, dentry->d_name.name); /* Init inode for quota operations. */ - vfs_dq_init(ip); + DQUOT_INIT(ip); if ((rc = get_UCSname(&dname, dentry))) goto out; @@ -1136,7 +1136,7 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, } else if (new_ip) { IWRITE_LOCK(new_ip, RDWRLOCK_NORMAL); /* Init inode for quota operations. */ - vfs_dq_init(new_ip); + DQUOT_INIT(new_ip); } /* @@ -1595,7 +1595,7 @@ static int jfs_ci_compare(struct dentry *dir, struct qstr *a, struct qstr *b) return result; } -const struct dentry_operations jfs_ci_dentry_operations = +struct dentry_operations jfs_ci_dentry_operations = { .d_hash = jfs_ci_hash, .d_compare = jfs_ci_compare, diff --git a/trunk/fs/jfs/xattr.c b/trunk/fs/jfs/xattr.c index 61dfa8173ebc..9b7f2cdaae0a 100644 --- a/trunk/fs/jfs/xattr.c +++ b/trunk/fs/jfs/xattr.c @@ -260,14 +260,14 @@ static int ea_write(struct inode *ip, struct jfs_ea_list *ealist, int size, nblocks = (size + (sb->s_blocksize - 1)) >> sb->s_blocksize_bits; /* Allocate new blocks to quota. */ - if (vfs_dq_alloc_block(ip, nblocks)) { + if (DQUOT_ALLOC_BLOCK(ip, nblocks)) { return -EDQUOT; } rc = dbAlloc(ip, INOHINT(ip), nblocks, &blkno); if (rc) { /*Rollback quota allocation. */ - vfs_dq_free_block(ip, nblocks); + DQUOT_FREE_BLOCK(ip, nblocks); return rc; } @@ -332,7 +332,7 @@ static int ea_write(struct inode *ip, struct jfs_ea_list *ealist, int size, failed: /* Rollback quota allocation. */ - vfs_dq_free_block(ip, nblocks); + DQUOT_FREE_BLOCK(ip, nblocks); dbFree(ip, blkno, nblocks); return rc; @@ -538,7 +538,7 @@ static int ea_get(struct inode *inode, struct ea_buffer *ea_buf, int min_size) if (blocks_needed > current_blocks) { /* Allocate new blocks to quota. */ - if (vfs_dq_alloc_block(inode, blocks_needed)) + if (DQUOT_ALLOC_BLOCK(inode, blocks_needed)) return -EDQUOT; quota_allocation = blocks_needed; @@ -602,7 +602,7 @@ static int ea_get(struct inode *inode, struct ea_buffer *ea_buf, int min_size) clean_up: /* Rollback quota allocation */ if (quota_allocation) - vfs_dq_free_block(inode, quota_allocation); + DQUOT_FREE_BLOCK(inode, quota_allocation); return (rc); } @@ -677,7 +677,7 @@ static int ea_put(tid_t tid, struct inode *inode, struct ea_buffer *ea_buf, /* If old blocks exist, they must be removed from quota allocation. */ if (old_blocks) - vfs_dq_free_block(inode, old_blocks); + DQUOT_FREE_BLOCK(inode, old_blocks); inode->i_ctime = CURRENT_TIME; diff --git a/trunk/fs/libfs.c b/trunk/fs/libfs.c index 4910a36f516e..49b44099dabb 100644 --- a/trunk/fs/libfs.c +++ b/trunk/fs/libfs.c @@ -44,7 +44,7 @@ static int simple_delete_dentry(struct dentry *dentry) */ struct dentry *simple_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) { - static const struct dentry_operations simple_dentry_operations = { + static struct dentry_operations simple_dentry_operations = { .d_delete = simple_delete_dentry, }; @@ -242,8 +242,7 @@ int get_sb_pseudo(struct file_system_type *fs_type, char *name, d_instantiate(dentry, root); s->s_root = dentry; s->s_flags |= MS_ACTIVE; - simple_set_mnt(mnt, s); - return 0; + return simple_set_mnt(mnt, s); Enomem: up_write(&s->s_umount); diff --git a/trunk/fs/namei.c b/trunk/fs/namei.c index d040ce11785d..199317642ad6 100644 --- a/trunk/fs/namei.c +++ b/trunk/fs/namei.c @@ -1473,7 +1473,7 @@ int vfs_create(struct inode *dir, struct dentry *dentry, int mode, error = security_inode_create(dir, dentry, mode); if (error) return error; - vfs_dq_init(dir); + DQUOT_INIT(dir); error = dir->i_op->create(dir, dentry, mode, nd); if (!error) fsnotify_create(dir, dentry); @@ -1489,22 +1489,24 @@ int may_open(struct path *path, int acc_mode, int flag) if (!inode) return -ENOENT; - switch (inode->i_mode & S_IFMT) { - case S_IFLNK: + if (S_ISLNK(inode->i_mode)) return -ELOOP; - case S_IFDIR: - if (acc_mode & MAY_WRITE) - return -EISDIR; - break; - case S_IFBLK: - case S_IFCHR: + + if (S_ISDIR(inode->i_mode) && (acc_mode & MAY_WRITE)) + return -EISDIR; + + /* + * FIFO's, sockets and device files are special: they don't + * actually live on the filesystem itself, and as such you + * can write to them even if the filesystem is read-only. + */ + if (S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) { + flag &= ~O_TRUNC; + } else if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) { if (path->mnt->mnt_flags & MNT_NODEV) return -EACCES; - /*FALLTHRU*/ - case S_IFIFO: - case S_IFSOCK: + flag &= ~O_TRUNC; - break; } error = inode_permission(inode, acc_mode); @@ -1550,7 +1552,7 @@ int may_open(struct path *path, int acc_mode, int flag) error = security_path_truncate(path, 0, ATTR_MTIME|ATTR_CTIME|ATTR_OPEN); if (!error) { - vfs_dq_init(inode); + DQUOT_INIT(inode); error = do_truncate(dentry, 0, ATTR_MTIME|ATTR_CTIME|ATTR_OPEN, @@ -1561,7 +1563,7 @@ int may_open(struct path *path, int acc_mode, int flag) return error; } else if (flag & FMODE_WRITE) - vfs_dq_init(inode); + DQUOT_INIT(inode); return 0; } @@ -1944,7 +1946,7 @@ int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) if (error) return error; - vfs_dq_init(dir); + DQUOT_INIT(dir); error = dir->i_op->mknod(dir, dentry, mode, dev); if (!error) fsnotify_create(dir, dentry); @@ -2043,7 +2045,7 @@ int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) if (error) return error; - vfs_dq_init(dir); + DQUOT_INIT(dir); error = dir->i_op->mkdir(dir, dentry, mode); if (!error) fsnotify_mkdir(dir, dentry); @@ -2129,7 +2131,7 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry) if (!dir->i_op->rmdir) return -EPERM; - vfs_dq_init(dir); + DQUOT_INIT(dir); mutex_lock(&dentry->d_inode->i_mutex); dentry_unhash(dentry); @@ -2216,7 +2218,7 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry) if (!dir->i_op->unlink) return -EPERM; - vfs_dq_init(dir); + DQUOT_INIT(dir); mutex_lock(&dentry->d_inode->i_mutex); if (d_mountpoint(dentry)) @@ -2327,7 +2329,7 @@ int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname) if (error) return error; - vfs_dq_init(dir); + DQUOT_INIT(dir); error = dir->i_op->symlink(dir, dentry, oldname); if (!error) fsnotify_create(dir, dentry); @@ -2411,7 +2413,7 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de return error; mutex_lock(&inode->i_mutex); - vfs_dq_init(dir); + DQUOT_INIT(dir); error = dir->i_op->link(old_dentry, dir, new_dentry); mutex_unlock(&inode->i_mutex); if (!error) @@ -2610,8 +2612,8 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, if (!old_dir->i_op->rename) return -EPERM; - vfs_dq_init(old_dir); - vfs_dq_init(new_dir); + DQUOT_INIT(old_dir); + DQUOT_INIT(new_dir); old_name = fsnotify_oldname_init(old_dentry->d_name.name); diff --git a/trunk/fs/namespace.c b/trunk/fs/namespace.c index 0a42e0e96027..f0e753097353 100644 --- a/trunk/fs/namespace.c +++ b/trunk/fs/namespace.c @@ -397,10 +397,11 @@ static void __mnt_unmake_readonly(struct vfsmount *mnt) spin_unlock(&vfsmount_lock); } -void simple_set_mnt(struct vfsmount *mnt, struct super_block *sb) +int simple_set_mnt(struct vfsmount *mnt, struct super_block *sb) { mnt->mnt_sb = sb; mnt->mnt_root = dget(sb->s_root); + return 0; } EXPORT_SYMBOL(simple_set_mnt); diff --git a/trunk/fs/ncpfs/dir.c b/trunk/fs/ncpfs/dir.c index 9c590722d87e..07e9715b8658 100644 --- a/trunk/fs/ncpfs/dir.c +++ b/trunk/fs/ncpfs/dir.c @@ -79,7 +79,7 @@ static int ncp_hash_dentry(struct dentry *, struct qstr *); static int ncp_compare_dentry (struct dentry *, struct qstr *, struct qstr *); static int ncp_delete_dentry(struct dentry *); -static const struct dentry_operations ncp_dentry_operations = +static struct dentry_operations ncp_dentry_operations = { .d_revalidate = ncp_lookup_validate, .d_hash = ncp_hash_dentry, @@ -87,7 +87,7 @@ static const struct dentry_operations ncp_dentry_operations = .d_delete = ncp_delete_dentry, }; -const struct dentry_operations ncp_root_dentry_operations = +struct dentry_operations ncp_root_dentry_operations = { .d_hash = ncp_hash_dentry, .d_compare = ncp_compare_dentry, diff --git a/trunk/fs/nfs/dir.c b/trunk/fs/nfs/dir.c index 78bf72fc1db3..672368f865ca 100644 --- a/trunk/fs/nfs/dir.c +++ b/trunk/fs/nfs/dir.c @@ -899,7 +899,7 @@ static void nfs_dentry_iput(struct dentry *dentry, struct inode *inode) iput(inode); } -const struct dentry_operations nfs_dentry_operations = { +struct dentry_operations nfs_dentry_operations = { .d_revalidate = nfs_lookup_revalidate, .d_delete = nfs_dentry_delete, .d_iput = nfs_dentry_iput, @@ -967,7 +967,7 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru #ifdef CONFIG_NFS_V4 static int nfs_open_revalidate(struct dentry *, struct nameidata *); -const struct dentry_operations nfs4_dentry_operations = { +struct dentry_operations nfs4_dentry_operations = { .d_revalidate = nfs_open_revalidate, .d_delete = nfs_dentry_delete, .d_iput = nfs_dentry_iput, diff --git a/trunk/fs/nfs/nfs4_fs.h b/trunk/fs/nfs/nfs4_fs.h index 84345deab26f..4e4d33204376 100644 --- a/trunk/fs/nfs/nfs4_fs.h +++ b/trunk/fs/nfs/nfs4_fs.h @@ -179,7 +179,7 @@ struct nfs4_state_recovery_ops { int (*recover_lock)(struct nfs4_state *, struct file_lock *); }; -extern const struct dentry_operations nfs4_dentry_operations; +extern struct dentry_operations nfs4_dentry_operations; extern const struct inode_operations nfs4_dir_inode_operations; /* inode.c */ diff --git a/trunk/fs/nfsd/vfs.c b/trunk/fs/nfsd/vfs.c index 78376b6c0236..c165a6403df0 100644 --- a/trunk/fs/nfsd/vfs.c +++ b/trunk/fs/nfsd/vfs.c @@ -356,7 +356,7 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap, put_write_access(inode); goto out_nfserr; } - vfs_dq_init(inode); + DQUOT_INIT(inode); } /* sanitize the mode change */ @@ -723,7 +723,7 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, else flags = O_WRONLY|O_LARGEFILE; - vfs_dq_init(inode); + DQUOT_INIT(inode); } *filp = dentry_open(dget(dentry), mntget(fhp->fh_export->ex_path.mnt), flags, cred); diff --git a/trunk/fs/notify/inotify/inotify.c b/trunk/fs/notify/inotify/inotify.c index 220c13f0d73d..331f2e88e284 100644 --- a/trunk/fs/notify/inotify/inotify.c +++ b/trunk/fs/notify/inotify/inotify.c @@ -379,14 +379,6 @@ void inotify_unmount_inodes(struct list_head *list) struct inode *need_iput_tmp; struct list_head *watches; - /* - * We cannot __iget() an inode in state I_CLEAR, I_FREEING, - * I_WILL_FREE, or I_NEW which is fine because by that point - * the inode cannot have any associated watches. - */ - if (inode->i_state & (I_CLEAR|I_FREEING|I_WILL_FREE|I_NEW)) - continue; - /* * If i_count is zero, the inode cannot have any watches and * doing an __iget/iput with MS_ACTIVE clear would actually @@ -396,6 +388,14 @@ void inotify_unmount_inodes(struct list_head *list) if (!atomic_read(&inode->i_count)) continue; + /* + * We cannot __iget() an inode in state I_CLEAR, I_FREEING, or + * I_WILL_FREE which is fine because by that point the inode + * cannot have any associated watches. + */ + if (inode->i_state & (I_CLEAR | I_FREEING | I_WILL_FREE)) + continue; + need_iput_tmp = need_iput; need_iput = NULL; /* In case inotify_remove_watch_locked() drops a reference. */ diff --git a/trunk/fs/ocfs2/dcache.c b/trunk/fs/ocfs2/dcache.c index 7d604480557a..e9d7c2038c0f 100644 --- a/trunk/fs/ocfs2/dcache.c +++ b/trunk/fs/ocfs2/dcache.c @@ -455,7 +455,7 @@ void ocfs2_dentry_move(struct dentry *dentry, struct dentry *target, d_move(dentry, target); } -const struct dentry_operations ocfs2_dentry_ops = { +struct dentry_operations ocfs2_dentry_ops = { .d_revalidate = ocfs2_dentry_revalidate, .d_iput = ocfs2_dentry_iput, }; diff --git a/trunk/fs/ocfs2/dcache.h b/trunk/fs/ocfs2/dcache.h index faa12e75f98d..d06e16c06640 100644 --- a/trunk/fs/ocfs2/dcache.h +++ b/trunk/fs/ocfs2/dcache.h @@ -26,7 +26,7 @@ #ifndef OCFS2_DCACHE_H #define OCFS2_DCACHE_H -extern const struct dentry_operations ocfs2_dentry_ops; +extern struct dentry_operations ocfs2_dentry_ops; struct ocfs2_dentry_lock { /* Use count of dentry lock */ diff --git a/trunk/fs/open.c b/trunk/fs/open.c index 75b61677daaf..a3a78ceb2a2b 100644 --- a/trunk/fs/open.c +++ b/trunk/fs/open.c @@ -273,7 +273,7 @@ static long do_sys_truncate(const char __user *pathname, loff_t length) if (!error) error = security_path_truncate(&path, length, 0); if (!error) { - vfs_dq_init(inode); + DQUOT_INIT(inode); error = do_truncate(path.dentry, length, 0, NULL); } diff --git a/trunk/fs/pipe.c b/trunk/fs/pipe.c index 4af7aa521813..94ad15967cf9 100644 --- a/trunk/fs/pipe.c +++ b/trunk/fs/pipe.c @@ -860,7 +860,7 @@ static char *pipefs_dname(struct dentry *dentry, char *buffer, int buflen) dentry->d_inode->i_ino); } -static const struct dentry_operations pipefs_dentry_operations = { +static struct dentry_operations pipefs_dentry_operations = { .d_delete = pipefs_delete_dentry, .d_dname = pipefs_dname, }; @@ -1024,6 +1024,11 @@ int do_pipe_flags(int *fd, int flags) return error; } +int do_pipe(int *fd) +{ + return do_pipe_flags(fd, 0); +} + /* * sys_pipe() is the normal C calling standard for creating * a pipe. It's not the way Unix traditionally does this, though. diff --git a/trunk/fs/proc/base.c b/trunk/fs/proc/base.c index aef6d55b7de6..beaa0ce3b82e 100644 --- a/trunk/fs/proc/base.c +++ b/trunk/fs/proc/base.c @@ -1545,7 +1545,7 @@ static int pid_delete_dentry(struct dentry * dentry) return !proc_pid(dentry->d_inode)->tasks[PIDTYPE_PID].first; } -static const struct dentry_operations pid_dentry_operations = +static struct dentry_operations pid_dentry_operations = { .d_revalidate = pid_revalidate, .d_delete = pid_delete_dentry, @@ -1717,7 +1717,7 @@ static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd) return 0; } -static const struct dentry_operations tid_fd_dentry_operations = +static struct dentry_operations tid_fd_dentry_operations = { .d_revalidate = tid_fd_revalidate, .d_delete = pid_delete_dentry, @@ -2339,7 +2339,7 @@ static int proc_base_revalidate(struct dentry *dentry, struct nameidata *nd) return 0; } -static const struct dentry_operations proc_base_dentry_operations = +static struct dentry_operations proc_base_dentry_operations = { .d_revalidate = proc_base_revalidate, .d_delete = pid_delete_dentry, diff --git a/trunk/fs/proc/generic.c b/trunk/fs/proc/generic.c index 5d2989e9dcc1..db7fa5cab988 100644 --- a/trunk/fs/proc/generic.c +++ b/trunk/fs/proc/generic.c @@ -363,7 +363,7 @@ static int proc_delete_dentry(struct dentry * dentry) return 1; } -static const struct dentry_operations proc_dentry_operations = +static struct dentry_operations proc_dentry_operations = { .d_delete = proc_delete_dentry, }; diff --git a/trunk/fs/proc/proc_sysctl.c b/trunk/fs/proc/proc_sysctl.c index 9b1e4e9a16bf..94fcfff6863a 100644 --- a/trunk/fs/proc/proc_sysctl.c +++ b/trunk/fs/proc/proc_sysctl.c @@ -7,7 +7,7 @@ #include #include "internal.h" -static const struct dentry_operations proc_sys_dentry_operations; +static struct dentry_operations proc_sys_dentry_operations; static const struct file_operations proc_sys_file_operations; static const struct inode_operations proc_sys_inode_operations; static const struct file_operations proc_sys_dir_file_operations; @@ -396,7 +396,7 @@ static int proc_sys_compare(struct dentry *dir, struct qstr *qstr, return !sysctl_is_seen(PROC_I(dentry->d_inode)->sysctl); } -static const struct dentry_operations proc_sys_dentry_operations = { +static struct dentry_operations proc_sys_dentry_operations = { .d_revalidate = proc_sys_revalidate, .d_delete = proc_sys_delete, .d_compare = proc_sys_compare, diff --git a/trunk/fs/proc/root.c b/trunk/fs/proc/root.c index 1e15a2b176e8..f6299a25594e 100644 --- a/trunk/fs/proc/root.c +++ b/trunk/fs/proc/root.c @@ -83,8 +83,7 @@ static int proc_get_sb(struct file_system_type *fs_type, ns->proc_mnt = mnt; } - simple_set_mnt(mnt, sb); - return 0; + return simple_set_mnt(mnt, sb); } static void proc_kill_sb(struct super_block *sb) diff --git a/trunk/fs/quota/quota.c b/trunk/fs/quota.c similarity index 94% rename from trunk/fs/quota/quota.c rename to trunk/fs/quota.c index b7f5a468f076..d76ada914f98 100644 --- a/trunk/fs/quota/quota.c +++ b/trunk/fs/quota.c @@ -20,8 +20,7 @@ #include /* Check validity of generic quotactl commands */ -static int generic_quotactl_valid(struct super_block *sb, int type, int cmd, - qid_t id) +static int generic_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t id) { if (type >= MAXQUOTAS) return -EINVAL; @@ -73,8 +72,7 @@ static int generic_quotactl_valid(struct super_block *sb, int type, int cmd, case Q_SETINFO: case Q_SETQUOTA: case Q_GETQUOTA: - /* This is just an informative test so we are satisfied - * without the lock */ + /* This is just informative test so we are satisfied without a lock */ if (!sb_has_quota_active(sb, type)) return -ESRCH; } @@ -94,8 +92,7 @@ static int generic_quotactl_valid(struct super_block *sb, int type, int cmd, } /* Check validity of XFS Quota Manager commands */ -static int xqm_quotactl_valid(struct super_block *sb, int type, int cmd, - qid_t id) +static int xqm_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t id) { if (type >= XQM_MAXQUOTAS) return -EINVAL; @@ -145,8 +142,7 @@ static int xqm_quotactl_valid(struct super_block *sb, int type, int cmd, return 0; } -static int check_quotactl_valid(struct super_block *sb, int type, int cmd, - qid_t id) +static int check_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t id) { int error; @@ -184,8 +180,7 @@ static void quota_sync_sb(struct super_block *sb, int type) continue; if (!sb_has_quota_active(sb, cnt)) continue; - mutex_lock_nested(&sb_dqopt(sb)->files[cnt]->i_mutex, - I_MUTEX_QUOTA); + mutex_lock_nested(&sb_dqopt(sb)->files[cnt]->i_mutex, I_MUTEX_QUOTA); truncate_inode_pages(&sb_dqopt(sb)->files[cnt]->i_data, 0); mutex_unlock(&sb_dqopt(sb)->files[cnt]->i_mutex); } @@ -205,15 +200,14 @@ void sync_dquots(struct super_block *sb, int type) spin_lock(&sb_lock); restart: list_for_each_entry(sb, &super_blocks, s_list) { - /* This test just improves performance so it needn't be - * reliable... */ + /* This test just improves performance so it needn't be reliable... */ for (cnt = 0; cnt < MAXQUOTAS; cnt++) { if (type != -1 && type != cnt) continue; if (!sb_has_quota_active(sb, cnt)) continue; if (!info_dirty(&sb_dqopt(sb)->info[cnt]) && - list_empty(&sb_dqopt(sb)->info[cnt].dqi_dirty_list)) + list_empty(&sb_dqopt(sb)->info[cnt].dqi_dirty_list)) continue; break; } @@ -233,8 +227,7 @@ void sync_dquots(struct super_block *sb, int type) } /* Copy parameters and call proper function */ -static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, - void __user *addr) +static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, void __user *addr) { int ret; @@ -242,8 +235,7 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, case Q_QUOTAON: { char *pathname; - pathname = getname(addr); - if (IS_ERR(pathname)) + if (IS_ERR(pathname = getname(addr))) return PTR_ERR(pathname); ret = sb->s_qcop->quota_on(sb, type, id, pathname, 0); putname(pathname); @@ -269,8 +261,7 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, case Q_GETINFO: { struct if_dqinfo info; - ret = sb->s_qcop->get_info(sb, type, &info); - if (ret) + if ((ret = sb->s_qcop->get_info(sb, type, &info))) return ret; if (copy_to_user(addr, &info, sizeof(info))) return -EFAULT; @@ -286,8 +277,7 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, case Q_GETQUOTA: { struct if_dqblk idq; - ret = sb->s_qcop->get_dqblk(sb, type, id, &idq); - if (ret) + if ((ret = sb->s_qcop->get_dqblk(sb, type, id, &idq))) return ret; if (copy_to_user(addr, &idq, sizeof(idq))) return -EFAULT; @@ -332,8 +322,7 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, case Q_XGETQUOTA: { struct fs_disk_quota fdq; - ret = sb->s_qcop->get_xquota(sb, type, id, &fdq); - if (ret) + if ((ret = sb->s_qcop->get_xquota(sb, type, id, &fdq))) return ret; if (copy_to_user(addr, &fdq, sizeof(fdq))) return -EFAULT; @@ -352,7 +341,7 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, * look up a superblock on which quota ops will be performed * - use the name of a block device to find the superblock thereon */ -static struct super_block *quotactl_block(const char __user *special) +static inline struct super_block *quotactl_block(const char __user *special) { #ifdef CONFIG_BLOCK struct block_device *bdev; diff --git a/trunk/fs/quota/Kconfig b/trunk/fs/quota/Kconfig deleted file mode 100644 index 8047e01ef46b..000000000000 --- a/trunk/fs/quota/Kconfig +++ /dev/null @@ -1,59 +0,0 @@ -# -# Quota configuration -# - -config QUOTA - bool "Quota support" - help - If you say Y here, you will be able to set per user limits for disk - usage (also called disk quotas). Currently, it works for the - ext2, ext3, and reiserfs file system. ext3 also supports journalled - quotas for which you don't need to run quotacheck(8) after an unclean - shutdown. - For further details, read the Quota mini-HOWTO, available from - , or the documentation provided - with the quota tools. Probably the quota support is only useful for - multi user systems. If unsure, say N. - -config QUOTA_NETLINK_INTERFACE - bool "Report quota messages through netlink interface" - depends on QUOTA && NET - help - If you say Y here, quota warnings (about exceeding softlimit, reaching - hardlimit, etc.) will be reported through netlink interface. If unsure, - say Y. - -config PRINT_QUOTA_WARNING - bool "Print quota warnings to console (OBSOLETE)" - depends on QUOTA - default y - help - If you say Y here, quota warnings (about exceeding softlimit, reaching - hardlimit, etc.) will be printed to the process' controlling terminal. - Note that this behavior is currently deprecated and may go away in - future. Please use notification via netlink socket instead. - -# Generic support for tree structured quota files. Selected when needed. -config QUOTA_TREE - tristate - -config QFMT_V1 - tristate "Old quota format support" - depends on QUOTA - help - This quota format was (is) used by kernels earlier than 2.4.22. If - you have quota working and you don't want to convert to new quota - format say Y here. - -config QFMT_V2 - tristate "Quota format v2 support" - depends on QUOTA - select QUOTA_TREE - help - This quota format allows using quotas with 32-bit UIDs/GIDs. If you - need this functionality say Y here. - -config QUOTACTL - bool - depends on XFS_QUOTA || QUOTA - default y diff --git a/trunk/fs/quota/Makefile b/trunk/fs/quota/Makefile deleted file mode 100644 index 385a0831cc99..000000000000 --- a/trunk/fs/quota/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# -# Makefile for the Linux filesystems. -# -# 14 Sep 2000, Christoph Hellwig -# Rewritten to use lists instead of if-statements. -# - -obj-y := - -obj-$(CONFIG_QUOTA) += dquot.o -obj-$(CONFIG_QFMT_V1) += quota_v1.o -obj-$(CONFIG_QFMT_V2) += quota_v2.o -obj-$(CONFIG_QUOTA_TREE) += quota_tree.o -obj-$(CONFIG_QUOTACTL) += quota.o diff --git a/trunk/fs/quota/quota_tree.c b/trunk/fs/quota_tree.c similarity index 84% rename from trunk/fs/quota/quota_tree.c rename to trunk/fs/quota_tree.c index f81f4bcfb178..953404c95b17 100644 --- a/trunk/fs/quota/quota_tree.c +++ b/trunk/fs/quota_tree.c @@ -22,6 +22,8 @@ MODULE_LICENSE("GPL"); #define __QUOTA_QT_PARANOIA +typedef char *dqbuf_t; + static int get_index(struct qtree_mem_dqinfo *info, qid_t id, int depth) { unsigned int epb = info->dqi_usable_bs >> 2; @@ -33,42 +35,46 @@ static int get_index(struct qtree_mem_dqinfo *info, qid_t id, int depth) } /* Number of entries in one blocks */ -static int qtree_dqstr_in_blk(struct qtree_mem_dqinfo *info) +static inline int qtree_dqstr_in_blk(struct qtree_mem_dqinfo *info) { return (info->dqi_usable_bs - sizeof(struct qt_disk_dqdbheader)) / info->dqi_entry_size; } -static char *getdqbuf(size_t size) +static dqbuf_t getdqbuf(size_t size) { - char *buf = kmalloc(size, GFP_NOFS); + dqbuf_t buf = kmalloc(size, GFP_NOFS); if (!buf) - printk(KERN_WARNING - "VFS: Not enough memory for quota buffers.\n"); + printk(KERN_WARNING "VFS: Not enough memory for quota buffers.\n"); return buf; } -static ssize_t read_blk(struct qtree_mem_dqinfo *info, uint blk, char *buf) +static inline void freedqbuf(dqbuf_t buf) +{ + kfree(buf); +} + +static inline ssize_t read_blk(struct qtree_mem_dqinfo *info, uint blk, dqbuf_t buf) { struct super_block *sb = info->dqi_sb; memset(buf, 0, info->dqi_usable_bs); - return sb->s_op->quota_read(sb, info->dqi_type, buf, + return sb->s_op->quota_read(sb, info->dqi_type, (char *)buf, info->dqi_usable_bs, blk << info->dqi_blocksize_bits); } -static ssize_t write_blk(struct qtree_mem_dqinfo *info, uint blk, char *buf) +static inline ssize_t write_blk(struct qtree_mem_dqinfo *info, uint blk, dqbuf_t buf) { struct super_block *sb = info->dqi_sb; - return sb->s_op->quota_write(sb, info->dqi_type, buf, + return sb->s_op->quota_write(sb, info->dqi_type, (char *)buf, info->dqi_usable_bs, blk << info->dqi_blocksize_bits); } /* Remove empty block from list and return it */ static int get_free_dqblk(struct qtree_mem_dqinfo *info) { - char *buf = getdqbuf(info->dqi_usable_bs); + dqbuf_t buf = getdqbuf(info->dqi_usable_bs); struct qt_disk_dqdbheader *dh = (struct qt_disk_dqdbheader *)buf; int ret, blk; @@ -92,12 +98,12 @@ static int get_free_dqblk(struct qtree_mem_dqinfo *info) mark_info_dirty(info->dqi_sb, info->dqi_type); ret = blk; out_buf: - kfree(buf); + freedqbuf(buf); return ret; } /* Insert empty block to the list */ -static int put_free_dqblk(struct qtree_mem_dqinfo *info, char *buf, uint blk) +static int put_free_dqblk(struct qtree_mem_dqinfo *info, dqbuf_t buf, uint blk) { struct qt_disk_dqdbheader *dh = (struct qt_disk_dqdbheader *)buf; int err; @@ -114,10 +120,9 @@ static int put_free_dqblk(struct qtree_mem_dqinfo *info, char *buf, uint blk) } /* Remove given block from the list of blocks with free entries */ -static int remove_free_dqentry(struct qtree_mem_dqinfo *info, char *buf, - uint blk) +static int remove_free_dqentry(struct qtree_mem_dqinfo *info, dqbuf_t buf, uint blk) { - char *tmpbuf = getdqbuf(info->dqi_usable_bs); + dqbuf_t tmpbuf = getdqbuf(info->dqi_usable_bs); struct qt_disk_dqdbheader *dh = (struct qt_disk_dqdbheader *)buf; uint nextblk = le32_to_cpu(dh->dqdh_next_free); uint prevblk = le32_to_cpu(dh->dqdh_prev_free); @@ -148,24 +153,21 @@ static int remove_free_dqentry(struct qtree_mem_dqinfo *info, char *buf, info->dqi_free_entry = nextblk; mark_info_dirty(info->dqi_sb, info->dqi_type); } - kfree(tmpbuf); + freedqbuf(tmpbuf); dh->dqdh_next_free = dh->dqdh_prev_free = cpu_to_le32(0); /* No matter whether write succeeds block is out of list */ if (write_blk(info, blk, buf) < 0) - printk(KERN_ERR - "VFS: Can't write block (%u) with free entries.\n", - blk); + printk(KERN_ERR "VFS: Can't write block (%u) with free entries.\n", blk); return 0; out_buf: - kfree(tmpbuf); + freedqbuf(tmpbuf); return err; } /* Insert given block to the beginning of list with free entries */ -static int insert_free_dqentry(struct qtree_mem_dqinfo *info, char *buf, - uint blk) +static int insert_free_dqentry(struct qtree_mem_dqinfo *info, dqbuf_t buf, uint blk) { - char *tmpbuf = getdqbuf(info->dqi_usable_bs); + dqbuf_t tmpbuf = getdqbuf(info->dqi_usable_bs); struct qt_disk_dqdbheader *dh = (struct qt_disk_dqdbheader *)buf; int err; @@ -186,12 +188,12 @@ static int insert_free_dqentry(struct qtree_mem_dqinfo *info, char *buf, if (err < 0) goto out_buf; } - kfree(tmpbuf); + freedqbuf(tmpbuf); info->dqi_free_entry = blk; mark_info_dirty(info->dqi_sb, info->dqi_type); return 0; out_buf: - kfree(tmpbuf); + freedqbuf(tmpbuf); return err; } @@ -213,7 +215,7 @@ static uint find_free_dqentry(struct qtree_mem_dqinfo *info, { uint blk, i; struct qt_disk_dqdbheader *dh; - char *buf = getdqbuf(info->dqi_usable_bs); + dqbuf_t buf = getdqbuf(info->dqi_usable_bs); char *ddquot; *err = 0; @@ -231,12 +233,11 @@ static uint find_free_dqentry(struct qtree_mem_dqinfo *info, blk = get_free_dqblk(info); if ((int)blk < 0) { *err = blk; - kfree(buf); + freedqbuf(buf); return 0; } memset(buf, 0, info->dqi_usable_bs); - /* This is enough as the block is already zeroed and the entry - * list is empty... */ + /* This is enough as block is already zeroed and entry list is empty... */ info->dqi_free_entry = blk; mark_info_dirty(dquot->dq_sb, dquot->dq_type); } @@ -252,12 +253,9 @@ static uint find_free_dqentry(struct qtree_mem_dqinfo *info, } le16_add_cpu(&dh->dqdh_entries, 1); /* Find free structure in block */ - ddquot = buf + sizeof(struct qt_disk_dqdbheader); - for (i = 0; i < qtree_dqstr_in_blk(info); i++) { - if (qtree_entry_unused(info, ddquot)) - break; - ddquot += info->dqi_entry_size; - } + for (i = 0, ddquot = ((char *)buf) + sizeof(struct qt_disk_dqdbheader); + i < qtree_dqstr_in_blk(info) && !qtree_entry_unused(info, ddquot); + i++, ddquot += info->dqi_entry_size); #ifdef __QUOTA_QT_PARANOIA if (i == qtree_dqstr_in_blk(info)) { printk(KERN_ERR "VFS: find_free_dqentry(): Data block full " @@ -275,10 +273,10 @@ static uint find_free_dqentry(struct qtree_mem_dqinfo *info, dquot->dq_off = (blk << info->dqi_blocksize_bits) + sizeof(struct qt_disk_dqdbheader) + i * info->dqi_entry_size; - kfree(buf); + freedqbuf(buf); return blk; out_buf: - kfree(buf); + freedqbuf(buf); return 0; } @@ -286,7 +284,7 @@ static uint find_free_dqentry(struct qtree_mem_dqinfo *info, static int do_insert_tree(struct qtree_mem_dqinfo *info, struct dquot *dquot, uint *treeblk, int depth) { - char *buf = getdqbuf(info->dqi_usable_bs); + dqbuf_t buf = getdqbuf(info->dqi_usable_bs); int ret = 0, newson = 0, newact = 0; __le32 *ref; uint newblk; @@ -335,7 +333,7 @@ static int do_insert_tree(struct qtree_mem_dqinfo *info, struct dquot *dquot, put_free_dqblk(info, buf, *treeblk); } out_buf: - kfree(buf); + freedqbuf(buf); return ret; } @@ -348,15 +346,14 @@ static inline int dq_insert_tree(struct qtree_mem_dqinfo *info, } /* - * We don't have to be afraid of deadlocks as we never have quotas on quota - * files... + * We don't have to be afraid of deadlocks as we never have quotas on quota files... */ int qtree_write_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot) { int type = dquot->dq_type; struct super_block *sb = dquot->dq_sb; ssize_t ret; - char *ddquot = getdqbuf(info->dqi_entry_size); + dqbuf_t ddquot = getdqbuf(info->dqi_entry_size); if (!ddquot) return -ENOMEM; @@ -367,15 +364,15 @@ int qtree_write_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot) if (ret < 0) { printk(KERN_ERR "VFS: Error %zd occurred while " "creating quota.\n", ret); - kfree(ddquot); + freedqbuf(ddquot); return ret; } } spin_lock(&dq_data_lock); info->dqi_ops->mem2disk_dqblk(ddquot, dquot); spin_unlock(&dq_data_lock); - ret = sb->s_op->quota_write(sb, type, ddquot, info->dqi_entry_size, - dquot->dq_off); + ret = sb->s_op->quota_write(sb, type, (char *)ddquot, + info->dqi_entry_size, dquot->dq_off); if (ret != info->dqi_entry_size) { printk(KERN_WARNING "VFS: dquota write failed on dev %s\n", sb->s_id); @@ -385,7 +382,7 @@ int qtree_write_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot) ret = 0; } dqstats.writes++; - kfree(ddquot); + freedqbuf(ddquot); return ret; } @@ -396,7 +393,7 @@ static int free_dqentry(struct qtree_mem_dqinfo *info, struct dquot *dquot, uint blk) { struct qt_disk_dqdbheader *dh; - char *buf = getdqbuf(info->dqi_usable_bs); + dqbuf_t buf = getdqbuf(info->dqi_usable_bs); int ret = 0; if (!buf) @@ -447,7 +444,7 @@ static int free_dqentry(struct qtree_mem_dqinfo *info, struct dquot *dquot, } dquot->dq_off = 0; /* Quota is now unattached */ out_buf: - kfree(buf); + freedqbuf(buf); return ret; } @@ -455,7 +452,7 @@ static int free_dqentry(struct qtree_mem_dqinfo *info, struct dquot *dquot, static int remove_tree(struct qtree_mem_dqinfo *info, struct dquot *dquot, uint *blk, int depth) { - char *buf = getdqbuf(info->dqi_usable_bs); + dqbuf_t buf = getdqbuf(info->dqi_usable_bs); int ret = 0; uint newblk; __le32 *ref = (__le32 *)buf; @@ -478,8 +475,9 @@ static int remove_tree(struct qtree_mem_dqinfo *info, struct dquot *dquot, int i; ref[get_index(info, dquot->dq_id, depth)] = cpu_to_le32(0); /* Block got empty? */ - for (i = 0; i < (info->dqi_usable_bs >> 2) && !ref[i]; i++) - ; + for (i = 0; + i < (info->dqi_usable_bs >> 2) && !ref[i]; + i++); /* Don't put the root block into the free block list */ if (i == (info->dqi_usable_bs >> 2) && *blk != QT_TREEOFF) { @@ -493,7 +491,7 @@ static int remove_tree(struct qtree_mem_dqinfo *info, struct dquot *dquot, } } out_buf: - kfree(buf); + freedqbuf(buf); return ret; } @@ -512,7 +510,7 @@ EXPORT_SYMBOL(qtree_delete_dquot); static loff_t find_block_dqentry(struct qtree_mem_dqinfo *info, struct dquot *dquot, uint blk) { - char *buf = getdqbuf(info->dqi_usable_bs); + dqbuf_t buf = getdqbuf(info->dqi_usable_bs); loff_t ret = 0; int i; char *ddquot; @@ -524,12 +522,9 @@ static loff_t find_block_dqentry(struct qtree_mem_dqinfo *info, printk(KERN_ERR "VFS: Can't read quota tree block %u.\n", blk); goto out_buf; } - ddquot = buf + sizeof(struct qt_disk_dqdbheader); - for (i = 0; i < qtree_dqstr_in_blk(info); i++) { - if (info->dqi_ops->is_id(ddquot, dquot)) - break; - ddquot += info->dqi_entry_size; - } + for (i = 0, ddquot = ((char *)buf) + sizeof(struct qt_disk_dqdbheader); + i < qtree_dqstr_in_blk(info) && !info->dqi_ops->is_id(ddquot, dquot); + i++, ddquot += info->dqi_entry_size); if (i == qtree_dqstr_in_blk(info)) { printk(KERN_ERR "VFS: Quota for id %u referenced " "but not present.\n", dquot->dq_id); @@ -540,7 +535,7 @@ static loff_t find_block_dqentry(struct qtree_mem_dqinfo *info, qt_disk_dqdbheader) + i * info->dqi_entry_size; } out_buf: - kfree(buf); + freedqbuf(buf); return ret; } @@ -548,7 +543,7 @@ static loff_t find_block_dqentry(struct qtree_mem_dqinfo *info, static loff_t find_tree_dqentry(struct qtree_mem_dqinfo *info, struct dquot *dquot, uint blk, int depth) { - char *buf = getdqbuf(info->dqi_usable_bs); + dqbuf_t buf = getdqbuf(info->dqi_usable_bs); loff_t ret = 0; __le32 *ref = (__le32 *)buf; @@ -568,7 +563,7 @@ static loff_t find_tree_dqentry(struct qtree_mem_dqinfo *info, else ret = find_block_dqentry(info, dquot, blk); out_buf: - kfree(buf); + freedqbuf(buf); return ret; } @@ -584,7 +579,7 @@ int qtree_read_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot) int type = dquot->dq_type; struct super_block *sb = dquot->dq_sb; loff_t offset; - char *ddquot; + dqbuf_t ddquot; int ret = 0; #ifdef __QUOTA_QT_PARANOIA @@ -612,8 +607,8 @@ int qtree_read_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot) ddquot = getdqbuf(info->dqi_entry_size); if (!ddquot) return -ENOMEM; - ret = sb->s_op->quota_read(sb, type, ddquot, info->dqi_entry_size, - dquot->dq_off); + ret = sb->s_op->quota_read(sb, type, (char *)ddquot, + info->dqi_entry_size, dquot->dq_off); if (ret != info->dqi_entry_size) { if (ret >= 0) ret = -EIO; @@ -621,7 +616,7 @@ int qtree_read_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot) "structure for id %u.\n", dquot->dq_id); set_bit(DQ_FAKE_B, &dquot->dq_flags); memset(&dquot->dq_dqb, 0, sizeof(struct mem_dqblk)); - kfree(ddquot); + freedqbuf(ddquot); goto out; } spin_lock(&dq_data_lock); @@ -632,7 +627,7 @@ int qtree_read_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot) !dquot->dq_dqb.dqb_isoftlimit) set_bit(DQ_FAKE_B, &dquot->dq_flags); spin_unlock(&dq_data_lock); - kfree(ddquot); + freedqbuf(ddquot); out: dqstats.reads++; return ret; @@ -643,8 +638,7 @@ EXPORT_SYMBOL(qtree_read_dquot); * the only one operating on dquot (thanks to dq_lock) */ int qtree_release_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot) { - if (test_bit(DQ_FAKE_B, &dquot->dq_flags) && - !(dquot->dq_dqb.dqb_curinodes | dquot->dq_dqb.dqb_curspace)) + if (test_bit(DQ_FAKE_B, &dquot->dq_flags) && !(dquot->dq_dqb.dqb_curinodes | dquot->dq_dqb.dqb_curspace)) return qtree_delete_dquot(info, dquot); return 0; } diff --git a/trunk/fs/quota/quota_tree.h b/trunk/fs/quota_tree.h similarity index 100% rename from trunk/fs/quota/quota_tree.h rename to trunk/fs/quota_tree.h diff --git a/trunk/fs/quota/quota_v1.c b/trunk/fs/quota_v1.c similarity index 79% rename from trunk/fs/quota/quota_v1.c rename to trunk/fs/quota_v1.c index 0edcf42b1778..b4af1c69ad16 100644 --- a/trunk/fs/quota/quota_v1.c +++ b/trunk/fs/quota_v1.c @@ -62,14 +62,11 @@ static int v1_read_dqblk(struct dquot *dquot) /* Set structure to 0s in case read fails/is after end of file */ memset(&dqblk, 0, sizeof(struct v1_disk_dqblk)); - dquot->dq_sb->s_op->quota_read(dquot->dq_sb, type, (char *)&dqblk, - sizeof(struct v1_disk_dqblk), v1_dqoff(dquot->dq_id)); + dquot->dq_sb->s_op->quota_read(dquot->dq_sb, type, (char *)&dqblk, sizeof(struct v1_disk_dqblk), v1_dqoff(dquot->dq_id)); v1_disk2mem_dqblk(&dquot->dq_dqb, &dqblk); - if (dquot->dq_dqb.dqb_bhardlimit == 0 && - dquot->dq_dqb.dqb_bsoftlimit == 0 && - dquot->dq_dqb.dqb_ihardlimit == 0 && - dquot->dq_dqb.dqb_isoftlimit == 0) + if (dquot->dq_dqb.dqb_bhardlimit == 0 && dquot->dq_dqb.dqb_bsoftlimit == 0 && + dquot->dq_dqb.dqb_ihardlimit == 0 && dquot->dq_dqb.dqb_isoftlimit == 0) set_bit(DQ_FAKE_B, &dquot->dq_flags); dqstats.reads++; @@ -84,16 +81,13 @@ static int v1_commit_dqblk(struct dquot *dquot) v1_mem2disk_dqblk(&dqblk, &dquot->dq_dqb); if (dquot->dq_id == 0) { - dqblk.dqb_btime = - sb_dqopt(dquot->dq_sb)->info[type].dqi_bgrace; - dqblk.dqb_itime = - sb_dqopt(dquot->dq_sb)->info[type].dqi_igrace; + dqblk.dqb_btime = sb_dqopt(dquot->dq_sb)->info[type].dqi_bgrace; + dqblk.dqb_itime = sb_dqopt(dquot->dq_sb)->info[type].dqi_igrace; } ret = 0; if (sb_dqopt(dquot->dq_sb)->files[type]) - ret = dquot->dq_sb->s_op->quota_write(dquot->dq_sb, type, - (char *)&dqblk, sizeof(struct v1_disk_dqblk), - v1_dqoff(dquot->dq_id)); + ret = dquot->dq_sb->s_op->quota_write(dquot->dq_sb, type, (char *)&dqblk, + sizeof(struct v1_disk_dqblk), v1_dqoff(dquot->dq_id)); if (ret != sizeof(struct v1_disk_dqblk)) { printk(KERN_WARNING "VFS: dquota write failed on dev %s\n", dquot->dq_sb->s_id); @@ -136,20 +130,15 @@ static int v1_check_quota_file(struct super_block *sb, int type) return 0; blocks = isize >> BLOCK_SIZE_BITS; off = isize & (BLOCK_SIZE - 1); - if ((blocks % sizeof(struct v1_disk_dqblk) * BLOCK_SIZE + off) % - sizeof(struct v1_disk_dqblk)) + if ((blocks % sizeof(struct v1_disk_dqblk) * BLOCK_SIZE + off) % sizeof(struct v1_disk_dqblk)) return 0; - /* Doublecheck whether we didn't get file with new format - with old - * quotactl() this could happen */ - size = sb->s_op->quota_read(sb, type, (char *)&dqhead, - sizeof(struct v2_disk_dqheader), 0); + /* Doublecheck whether we didn't get file with new format - with old quotactl() this could happen */ + size = sb->s_op->quota_read(sb, type, (char *)&dqhead, sizeof(struct v2_disk_dqheader), 0); if (size != sizeof(struct v2_disk_dqheader)) return 1; /* Probably not new format */ if (le32_to_cpu(dqhead.dqh_magic) != quota_magics[type]) return 1; /* Definitely not new format */ - printk(KERN_INFO - "VFS: %s: Refusing to turn on old quota format on given file." - " It probably contains newer quota format.\n", sb->s_id); + printk(KERN_INFO "VFS: %s: Refusing to turn on old quota format on given file. It probably contains newer quota format.\n", sb->s_id); return 0; /* Seems like a new format file -> refuse it */ } @@ -159,9 +148,7 @@ static int v1_read_file_info(struct super_block *sb, int type) struct v1_disk_dqblk dqblk; int ret; - ret = sb->s_op->quota_read(sb, type, (char *)&dqblk, - sizeof(struct v1_disk_dqblk), v1_dqoff(0)); - if (ret != sizeof(struct v1_disk_dqblk)) { + if ((ret = sb->s_op->quota_read(sb, type, (char *)&dqblk, sizeof(struct v1_disk_dqblk), v1_dqoff(0))) != sizeof(struct v1_disk_dqblk)) { if (ret >= 0) ret = -EIO; goto out; @@ -170,10 +157,8 @@ static int v1_read_file_info(struct super_block *sb, int type) /* limits are stored as unsigned 32-bit data */ dqopt->info[type].dqi_maxblimit = 0xffffffff; dqopt->info[type].dqi_maxilimit = 0xffffffff; - dqopt->info[type].dqi_igrace = - dqblk.dqb_itime ? dqblk.dqb_itime : MAX_IQ_TIME; - dqopt->info[type].dqi_bgrace = - dqblk.dqb_btime ? dqblk.dqb_btime : MAX_DQ_TIME; + dqopt->info[type].dqi_igrace = dqblk.dqb_itime ? dqblk.dqb_itime : MAX_IQ_TIME; + dqopt->info[type].dqi_bgrace = dqblk.dqb_btime ? dqblk.dqb_btime : MAX_DQ_TIME; out: return ret; } @@ -185,9 +170,8 @@ static int v1_write_file_info(struct super_block *sb, int type) int ret; dqopt->info[type].dqi_flags &= ~DQF_INFO_DIRTY; - ret = sb->s_op->quota_read(sb, type, (char *)&dqblk, - sizeof(struct v1_disk_dqblk), v1_dqoff(0)); - if (ret != sizeof(struct v1_disk_dqblk)) { + if ((ret = sb->s_op->quota_read(sb, type, (char *)&dqblk, + sizeof(struct v1_disk_dqblk), v1_dqoff(0))) != sizeof(struct v1_disk_dqblk)) { if (ret >= 0) ret = -EIO; goto out; diff --git a/trunk/fs/quota/quota_v2.c b/trunk/fs/quota_v2.c similarity index 98% rename from trunk/fs/quota/quota_v2.c rename to trunk/fs/quota_v2.c index a5475fb1ae44..b618b563635c 100644 --- a/trunk/fs/quota/quota_v2.c +++ b/trunk/fs/quota_v2.c @@ -54,8 +54,7 @@ static int v2_check_quota_file(struct super_block *sb, int type) static const uint quota_magics[] = V2_INITQMAGICS; static const uint quota_versions[] = V2_INITQVERSIONS; - size = sb->s_op->quota_read(sb, type, (char *)&dqhead, - sizeof(struct v2_disk_dqheader), 0); + size = sb->s_op->quota_read(sb, type, (char *)&dqhead, sizeof(struct v2_disk_dqheader), 0); if (size != sizeof(struct v2_disk_dqheader)) { printk("quota_v2: failed read expected=%zd got=%zd\n", sizeof(struct v2_disk_dqheader), size); diff --git a/trunk/fs/quota/quotaio_v1.h b/trunk/fs/quotaio_v1.h similarity index 100% rename from trunk/fs/quota/quotaio_v1.h rename to trunk/fs/quotaio_v1.h diff --git a/trunk/fs/quota/quotaio_v2.h b/trunk/fs/quotaio_v2.h similarity index 100% rename from trunk/fs/quota/quotaio_v2.h rename to trunk/fs/quotaio_v2.h diff --git a/trunk/fs/ramfs/file-nommu.c b/trunk/fs/ramfs/file-nommu.c index 995ef1d6686c..5d7c7ececa64 100644 --- a/trunk/fs/ramfs/file-nommu.c +++ b/trunk/fs/ramfs/file-nommu.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -204,6 +205,11 @@ static int ramfs_nommu_setattr(struct dentry *dentry, struct iattr *ia) if (ret) return ret; + /* by providing our own setattr() method, we skip this quotaism */ + if ((old_ia_valid & ATTR_UID && ia->ia_uid != inode->i_uid) || + (old_ia_valid & ATTR_GID && ia->ia_gid != inode->i_gid)) + ret = DQUOT_TRANSFER(inode, ia) ? -EDQUOT : 0; + /* pick out size-changing events */ if (ia->ia_valid & ATTR_SIZE) { loff_t size = i_size_read(inode); diff --git a/trunk/fs/reiserfs/bitmap.c b/trunk/fs/reiserfs/bitmap.c index f32d1425cc9f..4646caa60455 100644 --- a/trunk/fs/reiserfs/bitmap.c +++ b/trunk/fs/reiserfs/bitmap.c @@ -430,7 +430,7 @@ static void _reiserfs_free_block(struct reiserfs_transaction_handle *th, journal_mark_dirty(th, s, sbh); if (for_unformatted) - vfs_dq_free_block_nodirty(inode, 1); + DQUOT_FREE_BLOCK_NODIRTY(inode, 1); } void reiserfs_free_block(struct reiserfs_transaction_handle *th, @@ -1055,7 +1055,7 @@ static inline int blocknrs_and_prealloc_arrays_from_search_start amount_needed, hint->inode->i_uid); #endif quota_ret = - vfs_dq_alloc_block_nodirty(hint->inode, amount_needed); + DQUOT_ALLOC_BLOCK_NODIRTY(hint->inode, amount_needed); if (quota_ret) /* Quota exceeded? */ return QUOTA_EXCEEDED; if (hint->preallocate && hint->prealloc_size) { @@ -1064,7 +1064,8 @@ static inline int blocknrs_and_prealloc_arrays_from_search_start "reiserquota: allocating (prealloc) %d blocks id=%u", hint->prealloc_size, hint->inode->i_uid); #endif - quota_ret = vfs_dq_prealloc_block_nodirty(hint->inode, + quota_ret = + DQUOT_PREALLOC_BLOCK_NODIRTY(hint->inode, hint->prealloc_size); if (quota_ret) hint->preallocate = hint->prealloc_size = 0; @@ -1097,10 +1098,7 @@ static inline int blocknrs_and_prealloc_arrays_from_search_start nr_allocated, hint->inode->i_uid); #endif - /* Free not allocated blocks */ - vfs_dq_free_block_nodirty(hint->inode, - amount_needed + hint->prealloc_size - - nr_allocated); + DQUOT_FREE_BLOCK_NODIRTY(hint->inode, amount_needed + hint->prealloc_size - nr_allocated); /* Free not allocated blocks */ } while (nr_allocated--) reiserfs_free_block(hint->th, hint->inode, @@ -1131,7 +1129,7 @@ static inline int blocknrs_and_prealloc_arrays_from_search_start REISERFS_I(hint->inode)->i_prealloc_count, hint->inode->i_uid); #endif - vfs_dq_free_block_nodirty(hint->inode, amount_needed + + DQUOT_FREE_BLOCK_NODIRTY(hint->inode, amount_needed + hint->prealloc_size - nr_allocated - REISERFS_I(hint->inode)-> i_prealloc_count); diff --git a/trunk/fs/reiserfs/inode.c b/trunk/fs/reiserfs/inode.c index 823227a7662a..55fce92cdf18 100644 --- a/trunk/fs/reiserfs/inode.c +++ b/trunk/fs/reiserfs/inode.c @@ -53,7 +53,7 @@ void reiserfs_delete_inode(struct inode *inode) * after delete_object so that quota updates go into the same transaction as * stat data deletion */ if (!err) - vfs_dq_free_inode(inode); + DQUOT_FREE_INODE(inode); if (journal_end(&th, inode->i_sb, jbegin_count)) goto out; @@ -1763,7 +1763,7 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, BUG_ON(!th->t_trans_id); - if (vfs_dq_alloc_inode(inode)) { + if (DQUOT_ALLOC_INODE(inode)) { err = -EDQUOT; goto out_end_trans; } @@ -1947,12 +1947,12 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, INODE_PKEY(inode)->k_objectid = 0; /* Quota change must be inside a transaction for journaling */ - vfs_dq_free_inode(inode); + DQUOT_FREE_INODE(inode); out_end_trans: journal_end(th, th->t_super, th->t_blocks_allocated); /* Drop can be outside and it needs more credits so it's better to have it outside */ - vfs_dq_drop(inode); + DQUOT_DROP(inode); inode->i_flags |= S_NOQUOTA; make_bad_inode(inode); @@ -3119,7 +3119,7 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) if (error) goto out; error = - vfs_dq_transfer(inode, attr) ? -EDQUOT : 0; + DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0; if (error) { journal_end(&th, inode->i_sb, jbegin_count); diff --git a/trunk/fs/reiserfs/namei.c b/trunk/fs/reiserfs/namei.c index 639d635d9d4b..738967f6c8ee 100644 --- a/trunk/fs/reiserfs/namei.c +++ b/trunk/fs/reiserfs/namei.c @@ -555,7 +555,7 @@ static int reiserfs_add_entry(struct reiserfs_transaction_handle *th, */ static int drop_new_inode(struct inode *inode) { - vfs_dq_drop(inode); + DQUOT_DROP(inode); make_bad_inode(inode); inode->i_flags |= S_NOQUOTA; iput(inode); @@ -563,7 +563,7 @@ static int drop_new_inode(struct inode *inode) } /* utility function that does setup for reiserfs_new_inode. -** vfs_dq_init needs lots of credits so it's better to have it +** DQUOT_INIT needs lots of credits so it's better to have it ** outside of a transaction, so we had to pull some bits of ** reiserfs_new_inode out into this func. */ @@ -586,7 +586,7 @@ static int new_inode_init(struct inode *inode, struct inode *dir, int mode) } else { inode->i_gid = current_fsgid(); } - vfs_dq_init(inode); + DQUOT_INIT(inode); return 0; } diff --git a/trunk/fs/reiserfs/stree.c b/trunk/fs/reiserfs/stree.c index 73aaa33f6735..abbc64dcc8d4 100644 --- a/trunk/fs/reiserfs/stree.c +++ b/trunk/fs/reiserfs/stree.c @@ -1297,7 +1297,7 @@ int reiserfs_delete_item(struct reiserfs_transaction_handle *th, struct treepath "reiserquota delete_item(): freeing %u, id=%u type=%c", quota_cut_bytes, p_s_inode->i_uid, head2type(&s_ih)); #endif - vfs_dq_free_space_nodirty(p_s_inode, quota_cut_bytes); + DQUOT_FREE_SPACE_NODIRTY(p_s_inode, quota_cut_bytes); /* Return deleted body length */ return n_ret_value; @@ -1383,7 +1383,7 @@ void reiserfs_delete_solid_item(struct reiserfs_transaction_handle *th, quota_cut_bytes, inode->i_uid, key2type(key)); #endif - vfs_dq_free_space_nodirty(inode, + DQUOT_FREE_SPACE_NODIRTY(inode, quota_cut_bytes); } break; @@ -1734,7 +1734,7 @@ int reiserfs_cut_from_item(struct reiserfs_transaction_handle *th, "reiserquota cut_from_item(): freeing %u id=%u type=%c", quota_cut_bytes, p_s_inode->i_uid, '?'); #endif - vfs_dq_free_space_nodirty(p_s_inode, quota_cut_bytes); + DQUOT_FREE_SPACE_NODIRTY(p_s_inode, quota_cut_bytes); return n_ret_value; } @@ -1971,7 +1971,7 @@ int reiserfs_paste_into_item(struct reiserfs_transaction_handle *th, struct tree key2type(&(p_s_key->on_disk_key))); #endif - if (vfs_dq_alloc_space_nodirty(inode, n_pasted_size)) { + if (DQUOT_ALLOC_SPACE_NODIRTY(inode, n_pasted_size)) { pathrelse(p_s_search_path); return -EDQUOT; } @@ -2027,7 +2027,7 @@ int reiserfs_paste_into_item(struct reiserfs_transaction_handle *th, struct tree n_pasted_size, inode->i_uid, key2type(&(p_s_key->on_disk_key))); #endif - vfs_dq_free_space_nodirty(inode, n_pasted_size); + DQUOT_FREE_SPACE_NODIRTY(inode, n_pasted_size); return retval; } @@ -2060,7 +2060,7 @@ int reiserfs_insert_item(struct reiserfs_transaction_handle *th, struct treepath #endif /* We can't dirty inode here. It would be immediately written but * appropriate stat item isn't inserted yet... */ - if (vfs_dq_alloc_space_nodirty(inode, quota_bytes)) { + if (DQUOT_ALLOC_SPACE_NODIRTY(inode, quota_bytes)) { pathrelse(p_s_path); return -EDQUOT; } @@ -2112,6 +2112,6 @@ int reiserfs_insert_item(struct reiserfs_transaction_handle *th, struct treepath quota_bytes, inode->i_uid, head2type(p_s_ih)); #endif if (inode) - vfs_dq_free_space_nodirty(inode, quota_bytes); + DQUOT_FREE_SPACE_NODIRTY(inode, quota_bytes); return retval; } diff --git a/trunk/fs/reiserfs/super.c b/trunk/fs/reiserfs/super.c index 5dbafb739401..f3c820b75829 100644 --- a/trunk/fs/reiserfs/super.c +++ b/trunk/fs/reiserfs/super.c @@ -250,7 +250,7 @@ static int finish_unfinished(struct super_block *s) retval = remove_save_link_only(s, &save_link_key, 0); continue; } - vfs_dq_init(inode); + DQUOT_INIT(inode); if (truncate && S_ISDIR(inode->i_mode)) { /* We got a truncate request for a dir which is impossible. @@ -629,6 +629,8 @@ static const struct super_operations reiserfs_sops = { #ifdef CONFIG_QUOTA #define QTYPE2NAME(t) ((t)==USRQUOTA?"user":"group") +static int reiserfs_dquot_initialize(struct inode *, int); +static int reiserfs_dquot_drop(struct inode *); static int reiserfs_write_dquot(struct dquot *); static int reiserfs_acquire_dquot(struct dquot *); static int reiserfs_release_dquot(struct dquot *); @@ -637,8 +639,8 @@ static int reiserfs_write_info(struct super_block *, int); static int reiserfs_quota_on(struct super_block *, int, int, char *, int); static struct dquot_operations reiserfs_quota_operations = { - .initialize = dquot_initialize, - .drop = dquot_drop, + .initialize = reiserfs_dquot_initialize, + .drop = reiserfs_dquot_drop, .alloc_space = dquot_alloc_space, .alloc_inode = dquot_alloc_inode, .free_space = dquot_free_space, @@ -1894,6 +1896,58 @@ static int reiserfs_statfs(struct dentry *dentry, struct kstatfs *buf) } #ifdef CONFIG_QUOTA +static int reiserfs_dquot_initialize(struct inode *inode, int type) +{ + struct reiserfs_transaction_handle th; + int ret, err; + + /* We may create quota structure so we need to reserve enough blocks */ + reiserfs_write_lock(inode->i_sb); + ret = + journal_begin(&th, inode->i_sb, + 2 * REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb)); + if (ret) + goto out; + ret = dquot_initialize(inode, type); + err = + journal_end(&th, inode->i_sb, + 2 * REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb)); + if (!ret && err) + ret = err; + out: + reiserfs_write_unlock(inode->i_sb); + return ret; +} + +static int reiserfs_dquot_drop(struct inode *inode) +{ + struct reiserfs_transaction_handle th; + int ret, err; + + /* We may delete quota structure so we need to reserve enough blocks */ + reiserfs_write_lock(inode->i_sb); + ret = + journal_begin(&th, inode->i_sb, + 2 * REISERFS_QUOTA_DEL_BLOCKS(inode->i_sb)); + if (ret) { + /* + * We call dquot_drop() anyway to at least release references + * to quota structures so that umount does not hang. + */ + dquot_drop(inode); + goto out; + } + ret = dquot_drop(inode); + err = + journal_end(&th, inode->i_sb, + 2 * REISERFS_QUOTA_DEL_BLOCKS(inode->i_sb)); + if (!ret && err) + ret = err; + out: + reiserfs_write_unlock(inode->i_sb); + return ret; +} + static int reiserfs_write_dquot(struct dquot *dquot) { struct reiserfs_transaction_handle th; diff --git a/trunk/fs/reiserfs/xattr.c b/trunk/fs/reiserfs/xattr.c index ae881ccd2f03..ad92461cbfc3 100644 --- a/trunk/fs/reiserfs/xattr.c +++ b/trunk/fs/reiserfs/xattr.c @@ -1136,7 +1136,7 @@ xattr_lookup_poison(struct dentry *dentry, struct qstr *q1, struct qstr *name) return 1; } -static const struct dentry_operations xattr_lookup_poison_ops = { +static struct dentry_operations xattr_lookup_poison_ops = { .d_compare = xattr_lookup_poison, }; diff --git a/trunk/fs/smbfs/dir.c b/trunk/fs/smbfs/dir.c index 3e4803b4427e..e7ddd0328ddc 100644 --- a/trunk/fs/smbfs/dir.c +++ b/trunk/fs/smbfs/dir.c @@ -277,7 +277,7 @@ static int smb_hash_dentry(struct dentry *, struct qstr *); static int smb_compare_dentry(struct dentry *, struct qstr *, struct qstr *); static int smb_delete_dentry(struct dentry *); -static const struct dentry_operations smbfs_dentry_operations = +static struct dentry_operations smbfs_dentry_operations = { .d_revalidate = smb_lookup_validate, .d_hash = smb_hash_dentry, @@ -285,7 +285,7 @@ static const struct dentry_operations smbfs_dentry_operations = .d_delete = smb_delete_dentry, }; -static const struct dentry_operations smbfs_dentry_operations_case = +static struct dentry_operations smbfs_dentry_operations_case = { .d_revalidate = smb_lookup_validate, .d_delete = smb_delete_dentry, diff --git a/trunk/fs/super.c b/trunk/fs/super.c index 2ba481518ba7..dd4acb158b5e 100644 --- a/trunk/fs/super.c +++ b/trunk/fs/super.c @@ -197,7 +197,7 @@ void deactivate_super(struct super_block *s) if (atomic_dec_and_lock(&s->s_active, &sb_lock)) { s->s_count -= S_BIAS-1; spin_unlock(&sb_lock); - vfs_dq_off(s, 0); + DQUOT_OFF(s, 0); down_write(&s->s_umount); fs->kill_sb(s); put_filesystem(fs); @@ -266,7 +266,7 @@ EXPORT_SYMBOL(unlock_super); void __fsync_super(struct super_block *sb) { sync_inodes_sb(sb, 0); - vfs_dq_sync(sb); + DQUOT_SYNC(sb); lock_super(sb); if (sb->s_dirt && sb->s_op->write_super) sb->s_op->write_super(sb); @@ -655,7 +655,7 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force) mark_files_ro(sb); else if (!fs_may_remount_ro(sb)) return -EBUSY; - retval = vfs_dq_off(sb, 1); + retval = DQUOT_OFF(sb, 1); if (retval < 0 && retval != -ENOSYS) return -EBUSY; } @@ -670,7 +670,7 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force) } sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) | (flags & MS_RMT_MASK); if (remount_rw) - vfs_dq_quota_on_remount(sb); + DQUOT_ON_REMOUNT(sb); return 0; } @@ -838,8 +838,7 @@ int get_sb_bdev(struct file_system_type *fs_type, bdev->bd_super = s; } - simple_set_mnt(mnt, s); - return 0; + return simple_set_mnt(mnt, s); error_s: error = PTR_ERR(s); @@ -885,8 +884,7 @@ int get_sb_nodev(struct file_system_type *fs_type, return error; } s->s_flags |= MS_ACTIVE; - simple_set_mnt(mnt, s); - return 0; + return simple_set_mnt(mnt, s); } EXPORT_SYMBOL(get_sb_nodev); @@ -918,8 +916,7 @@ int get_sb_single(struct file_system_type *fs_type, s->s_flags |= MS_ACTIVE; } do_remount_sb(s, flags, data, 0); - simple_set_mnt(mnt, s); - return 0; + return simple_set_mnt(mnt, s); } EXPORT_SYMBOL(get_sb_single); diff --git a/trunk/fs/sync.c b/trunk/fs/sync.c index 7abc65fbf21d..ec95a69d17aa 100644 --- a/trunk/fs/sync.c +++ b/trunk/fs/sync.c @@ -25,7 +25,7 @@ static void do_sync(unsigned long wait) { wakeup_pdflush(0); sync_inodes(0); /* All mappings, inodes and their blockdevs */ - vfs_dq_sync(NULL); + DQUOT_SYNC(NULL); sync_supers(); /* Write the superblocks */ sync_filesystems(0); /* Start syncing the filesystems */ sync_filesystems(wait); /* Waitingly sync the filesystems */ diff --git a/trunk/fs/sysfs/dir.c b/trunk/fs/sysfs/dir.c index d88d0fac9fa5..66aeb4fff0c3 100644 --- a/trunk/fs/sysfs/dir.c +++ b/trunk/fs/sysfs/dir.c @@ -302,7 +302,7 @@ static void sysfs_d_iput(struct dentry * dentry, struct inode * inode) iput(inode); } -static const struct dentry_operations sysfs_dentry_ops = { +static struct dentry_operations sysfs_dentry_ops = { .d_iput = sysfs_d_iput, }; diff --git a/trunk/fs/sysv/namei.c b/trunk/fs/sysv/namei.c index 33e047b59b8d..a1f1ef33e81c 100644 --- a/trunk/fs/sysv/namei.c +++ b/trunk/fs/sysv/namei.c @@ -38,7 +38,7 @@ static int sysv_hash(struct dentry *dentry, struct qstr *qstr) return 0; } -const struct dentry_operations sysv_dentry_operations = { +struct dentry_operations sysv_dentry_operations = { .d_hash = sysv_hash, }; diff --git a/trunk/fs/sysv/sysv.h b/trunk/fs/sysv/sysv.h index 5784a318c883..38ebe3f85b3d 100644 --- a/trunk/fs/sysv/sysv.h +++ b/trunk/fs/sysv/sysv.h @@ -170,7 +170,7 @@ extern const struct file_operations sysv_file_operations; extern const struct file_operations sysv_dir_operations; extern const struct address_space_operations sysv_aops; extern const struct super_operations sysv_sops; -extern const struct dentry_operations sysv_dentry_operations; +extern struct dentry_operations sysv_dentry_operations; enum { diff --git a/trunk/fs/ubifs/super.c b/trunk/fs/ubifs/super.c index c5c98355459a..1182b66a5491 100644 --- a/trunk/fs/ubifs/super.c +++ b/trunk/fs/ubifs/super.c @@ -2034,8 +2034,7 @@ static int ubifs_get_sb(struct file_system_type *fs_type, int flags, /* 'fill_super()' opens ubi again so we must close it here */ ubi_close_volume(ubi); - simple_set_mnt(mnt, sb); - return 0; + return simple_set_mnt(mnt, sb); out_deact: up_write(&sb->s_umount); diff --git a/trunk/fs/udf/balloc.c b/trunk/fs/udf/balloc.c index 2bb788a2acb1..1b809bd494bd 100644 --- a/trunk/fs/udf/balloc.c +++ b/trunk/fs/udf/balloc.c @@ -206,7 +206,7 @@ static void udf_bitmap_free_blocks(struct super_block *sb, ((char *)bh->b_data)[(bit + i) >> 3]); } else { if (inode) - vfs_dq_free_block(inode, 1); + DQUOT_FREE_BLOCK(inode, 1); udf_add_free_space(sbi, sbi->s_partition, 1); } } @@ -261,11 +261,11 @@ static int udf_bitmap_prealloc_blocks(struct super_block *sb, while (bit < (sb->s_blocksize << 3) && block_count > 0) { if (!udf_test_bit(bit, bh->b_data)) goto out; - else if (vfs_dq_prealloc_block(inode, 1)) + else if (DQUOT_PREALLOC_BLOCK(inode, 1)) goto out; else if (!udf_clear_bit(bit, bh->b_data)) { udf_debug("bit already cleared for block %d\n", bit); - vfs_dq_free_block(inode, 1); + DQUOT_FREE_BLOCK(inode, 1); goto out; } block_count--; @@ -393,7 +393,7 @@ static int udf_bitmap_new_block(struct super_block *sb, /* * Check quota for allocation of this block. */ - if (inode && vfs_dq_alloc_block(inode, 1)) { + if (inode && DQUOT_ALLOC_BLOCK(inode, 1)) { mutex_unlock(&sbi->s_alloc_mutex); *err = -EDQUOT; return 0; @@ -452,7 +452,7 @@ static void udf_table_free_blocks(struct super_block *sb, /* We do this up front - There are some error conditions that could occure, but.. oh well */ if (inode) - vfs_dq_free_block(inode, count); + DQUOT_FREE_BLOCK(inode, count); if (udf_add_free_space(sbi, sbi->s_partition, count)) mark_buffer_dirty(sbi->s_lvid_bh); @@ -700,7 +700,7 @@ static int udf_table_prealloc_blocks(struct super_block *sb, epos.offset -= adsize; alloc_count = (elen >> sb->s_blocksize_bits); - if (inode && vfs_dq_prealloc_block(inode, + if (inode && DQUOT_PREALLOC_BLOCK(inode, alloc_count > block_count ? block_count : alloc_count)) alloc_count = 0; else if (alloc_count > block_count) { @@ -806,7 +806,7 @@ static int udf_table_new_block(struct super_block *sb, goal_eloc.logicalBlockNum++; goal_elen -= sb->s_blocksize; - if (inode && vfs_dq_alloc_block(inode, 1)) { + if (inode && DQUOT_ALLOC_BLOCK(inode, 1)) { brelse(goal_epos.bh); mutex_unlock(&sbi->s_alloc_mutex); *err = -EDQUOT; diff --git a/trunk/fs/udf/ialloc.c b/trunk/fs/udf/ialloc.c index 47dbe5613f90..31fc84297ddb 100644 --- a/trunk/fs/udf/ialloc.c +++ b/trunk/fs/udf/ialloc.c @@ -36,8 +36,8 @@ void udf_free_inode(struct inode *inode) * Note: we must free any quota before locking the superblock, * as writing the quota to disk may need the lock as well. */ - vfs_dq_free_inode(inode); - vfs_dq_drop(inode); + DQUOT_FREE_INODE(inode); + DQUOT_DROP(inode); clear_inode(inode); @@ -154,8 +154,8 @@ struct inode *udf_new_inode(struct inode *dir, int mode, int *err) insert_inode_hash(inode); mark_inode_dirty(inode); - if (vfs_dq_alloc_inode(inode)) { - vfs_dq_drop(inode); + if (DQUOT_ALLOC_INODE(inode)) { + DQUOT_DROP(inode); inode->i_flags |= S_NOQUOTA; inode->i_nlink = 0; iput(inode); diff --git a/trunk/fs/ufs/balloc.c b/trunk/fs/ufs/balloc.c index 54c16ec95dff..0d9ada173739 100644 --- a/trunk/fs/ufs/balloc.c +++ b/trunk/fs/ufs/balloc.c @@ -85,7 +85,7 @@ void ufs_free_fragments(struct inode *inode, u64 fragment, unsigned count) "bit already cleared for fragment %u", i); } - vfs_dq_free_block(inode, count); + DQUOT_FREE_BLOCK (inode, count); fs32_add(sb, &ucg->cg_cs.cs_nffree, count); @@ -195,7 +195,7 @@ void ufs_free_blocks(struct inode *inode, u64 fragment, unsigned count) ubh_setblock(UCPI_UBH(ucpi), ucpi->c_freeoff, blkno); if ((UFS_SB(sb)->s_flags & UFS_CG_MASK) == UFS_CG_44BSD) ufs_clusteracct (sb, ucpi, blkno, 1); - vfs_dq_free_block(inode, uspi->s_fpb); + DQUOT_FREE_BLOCK(inode, uspi->s_fpb); fs32_add(sb, &ucg->cg_cs.cs_nbfree, 1); uspi->cs_total.cs_nbfree++; @@ -556,7 +556,7 @@ static u64 ufs_add_fragments(struct inode *inode, u64 fragment, fs32_add(sb, &ucg->cg_frsum[fragsize - count], 1); for (i = oldcount; i < newcount; i++) ubh_clrbit (UCPI_UBH(ucpi), ucpi->c_freeoff, fragno + i); - if (vfs_dq_alloc_block(inode, count)) { + if(DQUOT_ALLOC_BLOCK(inode, count)) { *err = -EDQUOT; return 0; } @@ -664,7 +664,7 @@ static u64 ufs_alloc_fragments(struct inode *inode, unsigned cgno, for (i = count; i < uspi->s_fpb; i++) ubh_setbit (UCPI_UBH(ucpi), ucpi->c_freeoff, goal + i); i = uspi->s_fpb - count; - vfs_dq_free_block(inode, i); + DQUOT_FREE_BLOCK(inode, i); fs32_add(sb, &ucg->cg_cs.cs_nffree, i); uspi->cs_total.cs_nffree += i; @@ -676,7 +676,7 @@ static u64 ufs_alloc_fragments(struct inode *inode, unsigned cgno, result = ufs_bitmap_search (sb, ucpi, goal, allocsize); if (result == INVBLOCK) return 0; - if (vfs_dq_alloc_block(inode, count)) { + if(DQUOT_ALLOC_BLOCK(inode, count)) { *err = -EDQUOT; return 0; } @@ -747,7 +747,7 @@ static u64 ufs_alloccg_block(struct inode *inode, ubh_clrblock (UCPI_UBH(ucpi), ucpi->c_freeoff, blkno); if ((UFS_SB(sb)->s_flags & UFS_CG_MASK) == UFS_CG_44BSD) ufs_clusteracct (sb, ucpi, blkno, -1); - if (vfs_dq_alloc_block(inode, uspi->s_fpb)) { + if(DQUOT_ALLOC_BLOCK(inode, uspi->s_fpb)) { *err = -EDQUOT; return INVBLOCK; } diff --git a/trunk/fs/ufs/ialloc.c b/trunk/fs/ufs/ialloc.c index 3527c00fef0d..6f5dcf006096 100644 --- a/trunk/fs/ufs/ialloc.c +++ b/trunk/fs/ufs/ialloc.c @@ -95,8 +95,8 @@ void ufs_free_inode (struct inode * inode) is_directory = S_ISDIR(inode->i_mode); - vfs_dq_free_inode(inode); - vfs_dq_drop(inode); + DQUOT_FREE_INODE(inode); + DQUOT_DROP(inode); clear_inode (inode); @@ -355,8 +355,8 @@ struct inode * ufs_new_inode(struct inode * dir, int mode) unlock_super (sb); - if (vfs_dq_alloc_inode(inode)) { - vfs_dq_drop(inode); + if (DQUOT_ALLOC_INODE(inode)) { + DQUOT_DROP(inode); err = -EDQUOT; goto fail_without_unlock; } diff --git a/trunk/fs/ufs/inode.c b/trunk/fs/ufs/inode.c index 3d2512c21f05..39f877898565 100644 --- a/trunk/fs/ufs/inode.c +++ b/trunk/fs/ufs/inode.c @@ -622,6 +622,7 @@ static int ufs1_read_inode(struct inode *inode, struct ufs_inode *ufs_inode) struct ufs_inode_info *ufsi = UFS_I(inode); struct super_block *sb = inode->i_sb; mode_t mode; + unsigned i; /* * Copy data to the in-core inode. @@ -654,12 +655,11 @@ static int ufs1_read_inode(struct inode *inode, struct ufs_inode *ufs_inode) if (S_ISCHR(mode) || S_ISBLK(mode) || inode->i_blocks) { - memcpy(ufsi->i_u1.i_data, &ufs_inode->ui_u2.ui_addr, - sizeof(ufs_inode->ui_u2.ui_addr)); + for (i = 0; i < (UFS_NDADDR + UFS_NINDIR); i++) + ufsi->i_u1.i_data[i] = ufs_inode->ui_u2.ui_addr.ui_db[i]; } else { - memcpy(ufsi->i_u1.i_symlink, ufs_inode->ui_u2.ui_symlink, - sizeof(ufs_inode->ui_u2.ui_symlink) - 1); - ufsi->i_u1.i_symlink[sizeof(ufs_inode->ui_u2.ui_symlink) - 1] = 0; + for (i = 0; i < (UFS_NDADDR + UFS_NINDIR) * 4; i++) + ufsi->i_u1.i_symlink[i] = ufs_inode->ui_u2.ui_symlink[i]; } return 0; } @@ -669,6 +669,7 @@ static int ufs2_read_inode(struct inode *inode, struct ufs2_inode *ufs2_inode) struct ufs_inode_info *ufsi = UFS_I(inode); struct super_block *sb = inode->i_sb; mode_t mode; + unsigned i; UFSD("Reading ufs2 inode, ino %lu\n", inode->i_ino); /* @@ -703,12 +704,12 @@ static int ufs2_read_inode(struct inode *inode, struct ufs2_inode *ufs2_inode) */ if (S_ISCHR(mode) || S_ISBLK(mode) || inode->i_blocks) { - memcpy(ufsi->i_u1.u2_i_data, &ufs2_inode->ui_u2.ui_addr, - sizeof(ufs2_inode->ui_u2.ui_addr)); + for (i = 0; i < (UFS_NDADDR + UFS_NINDIR); i++) + ufsi->i_u1.u2_i_data[i] = + ufs2_inode->ui_u2.ui_addr.ui_db[i]; } else { - memcpy(ufsi->i_u1.i_symlink, ufs2_inode->ui_u2.ui_symlink, - sizeof(ufs2_inode->ui_u2.ui_symlink) - 1); - ufsi->i_u1.i_symlink[sizeof(ufs2_inode->ui_u2.ui_symlink) - 1] = 0; + for (i = 0; i < (UFS_NDADDR + UFS_NINDIR) * 4; i++) + ufsi->i_u1.i_symlink[i] = ufs2_inode->ui_u2.ui_symlink[i]; } return 0; } @@ -780,6 +781,7 @@ static void ufs1_update_inode(struct inode *inode, struct ufs_inode *ufs_inode) { struct super_block *sb = inode->i_sb; struct ufs_inode_info *ufsi = UFS_I(inode); + unsigned i; ufs_inode->ui_mode = cpu_to_fs16(sb, inode->i_mode); ufs_inode->ui_nlink = cpu_to_fs16(sb, inode->i_nlink); @@ -807,12 +809,12 @@ static void ufs1_update_inode(struct inode *inode, struct ufs_inode *ufs_inode) /* ufs_inode->ui_u2.ui_addr.ui_db[0] = cpu_to_fs32(sb, inode->i_rdev); */ ufs_inode->ui_u2.ui_addr.ui_db[0] = ufsi->i_u1.i_data[0]; } else if (inode->i_blocks) { - memcpy(&ufs_inode->ui_u2.ui_addr, ufsi->i_u1.i_data, - sizeof(ufs_inode->ui_u2.ui_addr)); + for (i = 0; i < (UFS_NDADDR + UFS_NINDIR); i++) + ufs_inode->ui_u2.ui_addr.ui_db[i] = ufsi->i_u1.i_data[i]; } else { - memcpy(&ufs_inode->ui_u2.ui_symlink, ufsi->i_u1.i_symlink, - sizeof(ufs_inode->ui_u2.ui_symlink)); + for (i = 0; i < (UFS_NDADDR + UFS_NINDIR) * 4; i++) + ufs_inode->ui_u2.ui_symlink[i] = ufsi->i_u1.i_symlink[i]; } if (!inode->i_nlink) @@ -823,6 +825,7 @@ static void ufs2_update_inode(struct inode *inode, struct ufs2_inode *ufs_inode) { struct super_block *sb = inode->i_sb; struct ufs_inode_info *ufsi = UFS_I(inode); + unsigned i; UFSD("ENTER\n"); ufs_inode->ui_mode = cpu_to_fs16(sb, inode->i_mode); @@ -847,11 +850,11 @@ static void ufs2_update_inode(struct inode *inode, struct ufs2_inode *ufs_inode) /* ufs_inode->ui_u2.ui_addr.ui_db[0] = cpu_to_fs32(sb, inode->i_rdev); */ ufs_inode->ui_u2.ui_addr.ui_db[0] = ufsi->i_u1.u2_i_data[0]; } else if (inode->i_blocks) { - memcpy(&ufs_inode->ui_u2.ui_addr, ufsi->i_u1.u2_i_data, - sizeof(ufs_inode->ui_u2.ui_addr)); + for (i = 0; i < (UFS_NDADDR + UFS_NINDIR); i++) + ufs_inode->ui_u2.ui_addr.ui_db[i] = ufsi->i_u1.u2_i_data[i]; } else { - memcpy(&ufs_inode->ui_u2.ui_symlink, ufsi->i_u1.i_symlink, - sizeof(ufs_inode->ui_u2.ui_symlink)); + for (i = 0; i < (UFS_NDADDR + UFS_NINDIR) * 4; i++) + ufs_inode->ui_u2.ui_symlink[i] = ufsi->i_u1.i_symlink[i]; } if (!inode->i_nlink) diff --git a/trunk/fs/ufs/namei.c b/trunk/fs/ufs/namei.c index 23119fe7ad62..e3a9b1fac75a 100644 --- a/trunk/fs/ufs/namei.c +++ b/trunk/fs/ufs/namei.c @@ -147,7 +147,7 @@ static int ufs_symlink (struct inode * dir, struct dentry * dentry, } else { /* fast symlink */ inode->i_op = &ufs_fast_symlink_inode_operations; - memcpy(UFS_I(inode)->i_u1.i_symlink, symname, l); + memcpy((char*)&UFS_I(inode)->i_u1.i_data,symname,l); inode->i_size = l-1; } mark_inode_dirty(inode); diff --git a/trunk/fs/ufs/super.c b/trunk/fs/ufs/super.c index e1c1fc5ee239..261a1c2f22dd 100644 --- a/trunk/fs/ufs/super.c +++ b/trunk/fs/ufs/super.c @@ -636,7 +636,6 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent) unsigned block_size, super_block_size; unsigned flags; unsigned super_block_offset; - unsigned maxsymlen; int ret = -EINVAL; uspi = NULL; @@ -1070,16 +1069,6 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent) uspi->s_maxsymlinklen = fs32_to_cpu(sb, usb3->fs_un2.fs_44.fs_maxsymlinklen); - if (uspi->fs_magic == UFS2_MAGIC) - maxsymlen = 2 * 4 * (UFS_NDADDR + UFS_NINDIR); - else - maxsymlen = 4 * (UFS_NDADDR + UFS_NINDIR); - if (uspi->s_maxsymlinklen > maxsymlen) { - ufs_warning(sb, __func__, "ufs_read_super: excessive maximum " - "fast symlink size (%u)\n", uspi->s_maxsymlinklen); - uspi->s_maxsymlinklen = maxsymlen; - } - inode = ufs_iget(sb, UFS_ROOTINO); if (IS_ERR(inode)) { ret = PTR_ERR(inode); diff --git a/trunk/fs/ufs/ufs.h b/trunk/fs/ufs/ufs.h index 69b3427d7885..11c035168ea6 100644 --- a/trunk/fs/ufs/ufs.h +++ b/trunk/fs/ufs/ufs.h @@ -23,7 +23,7 @@ struct ufs_sb_info { struct ufs_inode_info { union { __fs32 i_data[15]; - __u8 i_symlink[2 * 4 * 15]; + __u8 i_symlink[4*15]; __fs64 u2_i_data[15]; } i_u1; __u32 i_flags; diff --git a/trunk/include/linux/buffer_head.h b/trunk/include/linux/buffer_head.h index f19fd9045ea0..bd7ac793be19 100644 --- a/trunk/include/linux/buffer_head.h +++ b/trunk/include/linux/buffer_head.h @@ -165,8 +165,15 @@ int sync_mapping_buffers(struct address_space *mapping); void unmap_underlying_metadata(struct block_device *bdev, sector_t block); void mark_buffer_async_write(struct buffer_head *bh); +void invalidate_bdev(struct block_device *); +int sync_blockdev(struct block_device *bdev); void __wait_on_buffer(struct buffer_head *); wait_queue_head_t *bh_waitq_head(struct buffer_head *bh); +int fsync_bdev(struct block_device *); +struct super_block *freeze_bdev(struct block_device *); +int thaw_bdev(struct block_device *, struct super_block *); +int fsync_super(struct super_block *); +int fsync_no_super(struct block_device *); struct buffer_head *__find_get_block(struct block_device *bdev, sector_t block, unsigned size); struct buffer_head *__getblk(struct block_device *bdev, sector_t block, diff --git a/trunk/include/linux/compat.h b/trunk/include/linux/compat.h index b880864672de..3fd2194ff573 100644 --- a/trunk/include/linux/compat.h +++ b/trunk/include/linux/compat.h @@ -125,13 +125,6 @@ struct compat_dirent { char d_name[256]; }; -struct compat_ustat { - compat_daddr_t f_tfree; - compat_ino_t f_tinode; - char f_fname[6]; - char f_fpack[6]; -}; - typedef union compat_sigval { compat_int_t sival_int; compat_uptr_t sival_ptr; @@ -185,7 +178,6 @@ long compat_sys_semtimedop(int semid, struct sembuf __user *tsems, unsigned nsems, const struct compat_timespec __user *timeout); asmlinkage long compat_sys_keyctl(u32 option, u32 arg2, u32 arg3, u32 arg4, u32 arg5); -asmlinkage long compat_sys_ustat(unsigned dev, struct compat_ustat __user *u32); asmlinkage ssize_t compat_sys_readv(unsigned long fd, const struct compat_iovec __user *vec, unsigned long vlen); diff --git a/trunk/include/linux/dcache.h b/trunk/include/linux/dcache.h index 15156364d196..c66d22487bf8 100644 --- a/trunk/include/linux/dcache.h +++ b/trunk/include/linux/dcache.h @@ -112,7 +112,7 @@ struct dentry { struct list_head d_subdirs; /* our children */ struct list_head d_alias; /* inode alias list */ unsigned long d_time; /* used by d_revalidate */ - const struct dentry_operations *d_op; + struct dentry_operations *d_op; struct super_block *d_sb; /* The root of the dentry tree */ void *d_fsdata; /* fs-specific data */ diff --git a/trunk/include/linux/fs.h b/trunk/include/linux/fs.h index 42436ae42f70..1cd44f727dac 100644 --- a/trunk/include/linux/fs.h +++ b/trunk/include/linux/fs.h @@ -1064,147 +1064,34 @@ extern int lease_modify(struct file_lock **, int); extern int lock_may_read(struct inode *, loff_t start, unsigned long count); extern int lock_may_write(struct inode *, loff_t start, unsigned long count); #else /* !CONFIG_FILE_LOCKING */ -static inline int fcntl_getlk(struct file *file, struct flock __user *user) -{ - return -EINVAL; -} - -static inline int fcntl_setlk(unsigned int fd, struct file *file, - unsigned int cmd, struct flock __user *user) -{ - return -EACCES; -} - +#define fcntl_getlk(a, b) ({ -EINVAL; }) +#define fcntl_setlk(a, b, c, d) ({ -EACCES; }) #if BITS_PER_LONG == 32 -static inline int fcntl_getlk64(struct file *file, struct flock64 __user *user) -{ - return -EINVAL; -} - -static inline int fcntl_setlk64(unsigned int fd, struct file *file, - unsigned int cmd, struct flock64 __user *user) -{ - return -EACCES; -} +#define fcntl_getlk64(a, b) ({ -EINVAL; }) +#define fcntl_setlk64(a, b, c, d) ({ -EACCES; }) #endif -static inline int fcntl_setlease(unsigned int fd, struct file *filp, long arg) -{ - return 0; -} - -static inline int fcntl_getlease(struct file *filp) -{ - return 0; -} - -static inline void locks_init_lock(struct file_lock *fl) -{ - return; -} - -static inline void __locks_copy_lock(struct file_lock *new, struct file_lock *fl) -{ - return; -} - -static inline void locks_copy_lock(struct file_lock *new, struct file_lock *fl) -{ - return; -} - -static inline void locks_remove_posix(struct file *filp, fl_owner_t owner) -{ - return; -} - -static inline void locks_remove_flock(struct file *filp) -{ - return; -} - -static inline void posix_test_lock(struct file *filp, struct file_lock *fl) -{ - return; -} - -static inline int posix_lock_file(struct file *filp, struct file_lock *fl, - struct file_lock *conflock) -{ - return -ENOLCK; -} - -static inline int posix_lock_file_wait(struct file *filp, struct file_lock *fl) -{ - return -ENOLCK; -} - -static inline int posix_unblock_lock(struct file *filp, - struct file_lock *waiter) -{ - return -ENOENT; -} - -static inline int vfs_test_lock(struct file *filp, struct file_lock *fl) -{ - return 0; -} - -static inline int vfs_lock_file(struct file *filp, unsigned int cmd, - struct file_lock *fl, struct file_lock *conf) -{ - return -ENOLCK; -} - -static inline int vfs_cancel_lock(struct file *filp, struct file_lock *fl) -{ - return 0; -} - -static inline int flock_lock_file_wait(struct file *filp, - struct file_lock *request) -{ - return -ENOLCK; -} - -static inline int __break_lease(struct inode *inode, unsigned int mode) -{ - return 0; -} - -static inline void lease_get_mtime(struct inode *inode, struct timespec *time) -{ - return; -} - -static inline int generic_setlease(struct file *filp, long arg, - struct file_lock **flp) -{ - return -EINVAL; -} - -static inline int vfs_setlease(struct file *filp, long arg, - struct file_lock **lease) -{ - return -EINVAL; -} - -static inline int lease_modify(struct file_lock **before, int arg) -{ - return -EINVAL; -} - -static inline int lock_may_read(struct inode *inode, loff_t start, - unsigned long len) -{ - return 1; -} - -static inline int lock_may_write(struct inode *inode, loff_t start, - unsigned long len) -{ - return 1; -} - +#define fcntl_setlease(a, b, c) ({ 0; }) +#define fcntl_getlease(a) ({ 0; }) +#define locks_init_lock(a) ({ }) +#define __locks_copy_lock(a, b) ({ }) +#define locks_copy_lock(a, b) ({ }) +#define locks_remove_posix(a, b) ({ }) +#define locks_remove_flock(a) ({ }) +#define posix_test_lock(a, b) ({ 0; }) +#define posix_lock_file(a, b, c) ({ -ENOLCK; }) +#define posix_lock_file_wait(a, b) ({ -ENOLCK; }) +#define posix_unblock_lock(a, b) (-ENOENT) +#define vfs_test_lock(a, b) ({ 0; }) +#define vfs_lock_file(a, b, c, d) (-ENOLCK) +#define vfs_cancel_lock(a, b) ({ 0; }) +#define flock_lock_file_wait(a, b) ({ -ENOLCK; }) +#define __break_lease(a, b) ({ 0; }) +#define lease_get_mtime(a, b) ({ }) +#define generic_setlease(a, b, c) ({ -EINVAL; }) +#define vfs_setlease(a, b, c) ({ -EINVAL; }) +#define lease_modify(a, b) ({ -EINVAL; }) +#define lock_may_read(a, b, c) ({ 1; }) +#define lock_may_write(a, b, c) ({ 1; }) #endif /* !CONFIG_FILE_LOCKING */ @@ -1720,7 +1607,7 @@ struct super_block *sget(struct file_system_type *type, extern int get_sb_pseudo(struct file_system_type *, char *, const struct super_operations *ops, unsigned long, struct vfsmount *mnt); -extern void simple_set_mnt(struct vfsmount *mnt, struct super_block *sb); +extern int simple_set_mnt(struct vfsmount *mnt, struct super_block *sb); int __put_super_and_need_restart(struct super_block *sb); /* Alas, no aliases. Too much hassle with bringing module.h everywhere */ @@ -1801,44 +1688,13 @@ static inline int break_lease(struct inode *inode, unsigned int mode) return 0; } #else /* !CONFIG_FILE_LOCKING */ -static inline int locks_mandatory_locked(struct inode *inode) -{ - return 0; -} - -static inline int locks_mandatory_area(int rw, struct inode *inode, - struct file *filp, loff_t offset, - size_t count) -{ - return 0; -} - -static inline int __mandatory_lock(struct inode *inode) -{ - return 0; -} - -static inline int mandatory_lock(struct inode *inode) -{ - return 0; -} - -static inline int locks_verify_locked(struct inode *inode) -{ - return 0; -} - -static inline int locks_verify_truncate(struct inode *inode, struct file *filp, - size_t size) -{ - return 0; -} - -static inline int break_lease(struct inode *inode, unsigned int mode) -{ - return 0; -} - +#define locks_mandatory_locked(a) ({ 0; }) +#define locks_mandatory_area(a, b, c, d, e) ({ 0; }) +#define __mandatory_lock(a) ({ 0; }) +#define mandatory_lock(a) ({ 0; }) +#define locks_verify_locked(a) ({ 0; }) +#define locks_verify_truncate(a, b, c) ({ 0; }) +#define break_lease(a, b) ({ 0; }) #endif /* CONFIG_FILE_LOCKING */ /* fs/open.c */ @@ -1875,13 +1731,6 @@ extern void bd_set_size(struct block_device *, loff_t size); extern void bd_forget(struct inode *inode); extern void bdput(struct block_device *); extern struct block_device *open_by_devnum(dev_t, fmode_t); -extern void invalidate_bdev(struct block_device *); -extern int sync_blockdev(struct block_device *bdev); -extern struct super_block *freeze_bdev(struct block_device *); -extern int thaw_bdev(struct block_device *bdev, struct super_block *sb); -extern int fsync_bdev(struct block_device *); -extern int fsync_super(struct super_block *); -extern int fsync_no_super(struct block_device *); #else static inline void bd_forget(struct inode *inode) {} #endif @@ -2033,6 +1882,7 @@ static inline void allow_write_access(struct file *file) if (file) atomic_inc(&file->f_path.dentry->d_inode->i_writecount); } +extern int do_pipe(int *); extern int do_pipe_flags(int *, int); extern struct file *create_read_pipe(struct file *f, int flags); extern struct file *create_write_pipe(int flags); diff --git a/trunk/include/linux/ncp_fs.h b/trunk/include/linux/ncp_fs.h index 30b06c893944..f69e66d151cc 100644 --- a/trunk/include/linux/ncp_fs.h +++ b/trunk/include/linux/ncp_fs.h @@ -204,7 +204,7 @@ void ncp_update_inode2(struct inode *, struct ncp_entry_info *); /* linux/fs/ncpfs/dir.c */ extern const struct inode_operations ncp_dir_inode_operations; extern const struct file_operations ncp_dir_operations; -extern const struct dentry_operations ncp_root_dentry_operations; +extern struct dentry_operations ncp_root_dentry_operations; int ncp_conn_logged_in(struct super_block *); int ncp_date_dos2unix(__le16 time, __le16 date); void ncp_date_unix2dos(int unix_date, __le16 * time, __le16 * date); diff --git a/trunk/include/linux/nfs_fs.h b/trunk/include/linux/nfs_fs.h index 8cc8807f77d6..db867b04ac3c 100644 --- a/trunk/include/linux/nfs_fs.h +++ b/trunk/include/linux/nfs_fs.h @@ -415,7 +415,7 @@ extern const struct inode_operations nfs_dir_inode_operations; extern const struct inode_operations nfs3_dir_inode_operations; #endif /* CONFIG_NFS_V3 */ extern const struct file_operations nfs_dir_operations; -extern const struct dentry_operations nfs_dentry_operations; +extern struct dentry_operations nfs_dentry_operations; extern void nfs_force_lookup_revalidate(struct inode *dir); extern int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fh, struct nfs_fattr *fattr); diff --git a/trunk/include/linux/nfs_xdr.h b/trunk/include/linux/nfs_xdr.h index 43a713fce11c..2e5f00066afd 100644 --- a/trunk/include/linux/nfs_xdr.h +++ b/trunk/include/linux/nfs_xdr.h @@ -785,7 +785,7 @@ struct nfs_access_entry; */ struct nfs_rpc_ops { u32 version; /* Protocol version */ - const struct dentry_operations *dentry_ops; + struct dentry_operations *dentry_ops; const struct inode_operations *dir_inode_ops; const struct inode_operations *file_inode_ops; diff --git a/trunk/include/linux/quota.h b/trunk/include/linux/quota.h index 78c48895b12a..d72d5d84fde5 100644 --- a/trunk/include/linux/quota.h +++ b/trunk/include/linux/quota.h @@ -198,7 +198,6 @@ struct mem_dqblk { qsize_t dqb_bhardlimit; /* absolute limit on disk blks alloc */ qsize_t dqb_bsoftlimit; /* preferred limit on disk blks */ qsize_t dqb_curspace; /* current used space */ - qsize_t dqb_rsvspace; /* current reserved space for delalloc*/ qsize_t dqb_ihardlimit; /* absolute limit on allocated inodes */ qsize_t dqb_isoftlimit; /* preferred inode limit */ qsize_t dqb_curinodes; /* current # allocated inodes */ @@ -277,6 +276,8 @@ struct dquot { struct mem_dqblk dq_dqb; /* Diskquota usage */ }; +#define NODQUOT (struct dquot *)NULL + #define QUOTA_OK 0 #define NO_QUOTA 1 @@ -307,14 +308,6 @@ struct dquot_operations { int (*release_dquot) (struct dquot *); /* Quota is going to be deleted from disk */ int (*mark_dirty) (struct dquot *); /* Dquot is marked dirty */ int (*write_info) (struct super_block *, int); /* Write of quota "superblock" */ - /* reserve quota for delayed block allocation */ - int (*reserve_space) (struct inode *, qsize_t, int); - /* claim reserved quota for delayed alloc */ - int (*claim_space) (struct inode *, qsize_t); - /* release rsved quota for delayed alloc */ - void (*release_rsv) (struct inode *, qsize_t); - /* get reserved quota for delayed alloc */ - qsize_t (*get_reserved_space) (struct inode *); }; /* Operations handling requests from userspace */ diff --git a/trunk/include/linux/quotaops.h b/trunk/include/linux/quotaops.h index 36353d95c8db..0b35b3a1be05 100644 --- a/trunk/include/linux/quotaops.h +++ b/trunk/include/linux/quotaops.h @@ -35,11 +35,6 @@ void dquot_destroy(struct dquot *dquot); int dquot_alloc_space(struct inode *inode, qsize_t number, int prealloc); int dquot_alloc_inode(const struct inode *inode, qsize_t number); -int dquot_reserve_space(struct inode *inode, qsize_t number, int prealloc); -int dquot_claim_space(struct inode *inode, qsize_t number); -void dquot_release_reserved_space(struct inode *inode, qsize_t number); -qsize_t dquot_get_reserved_space(struct inode *inode); - int dquot_free_space(struct inode *inode, qsize_t number); int dquot_free_inode(const struct inode *inode, qsize_t number); @@ -188,16 +183,6 @@ static inline int vfs_dq_alloc_space(struct inode *inode, qsize_t nr) return ret; } -static inline int vfs_dq_reserve_space(struct inode *inode, qsize_t nr) -{ - if (sb_any_quota_active(inode->i_sb)) { - /* Used space is updated in alloc_space() */ - if (inode->i_sb->dq_op->reserve_space(inode, nr, 0) == NO_QUOTA) - return 1; - } - return 0; -} - static inline int vfs_dq_alloc_inode(struct inode *inode) { if (sb_any_quota_active(inode->i_sb)) { @@ -208,31 +193,6 @@ static inline int vfs_dq_alloc_inode(struct inode *inode) return 0; } -/* - * Convert in-memory reserved quotas to real consumed quotas - */ -static inline int vfs_dq_claim_space(struct inode *inode, qsize_t nr) -{ - if (sb_any_quota_active(inode->i_sb)) { - if (inode->i_sb->dq_op->claim_space(inode, nr) == NO_QUOTA) - return 1; - } else - inode_add_bytes(inode, nr); - - mark_inode_dirty(inode); - return 0; -} - -/* - * Release reserved (in-memory) quotas - */ -static inline -void vfs_dq_release_reservation_space(struct inode *inode, qsize_t nr) -{ - if (sb_any_quota_active(inode->i_sb)) - inode->i_sb->dq_op->release_rsv(inode, nr); -} - static inline void vfs_dq_free_space_nodirty(struct inode *inode, qsize_t nr) { if (sb_any_quota_active(inode->i_sb)) @@ -379,22 +339,6 @@ static inline int vfs_dq_alloc_space(struct inode *inode, qsize_t nr) return 0; } -static inline int vfs_dq_reserve_space(struct inode *inode, qsize_t nr) -{ - return 0; -} - -static inline int vfs_dq_claim_space(struct inode *inode, qsize_t nr) -{ - return vfs_dq_alloc_space(inode, nr); -} - -static inline -int vfs_dq_release_reservation_space(struct inode *inode, qsize_t nr) -{ - return 0; -} - static inline void vfs_dq_free_space_nodirty(struct inode *inode, qsize_t nr) { inode_sub_bytes(inode, nr); @@ -410,48 +354,67 @@ static inline void vfs_dq_free_space(struct inode *inode, qsize_t nr) static inline int vfs_dq_prealloc_block_nodirty(struct inode *inode, qsize_t nr) { - return vfs_dq_prealloc_space_nodirty(inode, nr << inode->i_blkbits); + return vfs_dq_prealloc_space_nodirty(inode, + nr << inode->i_sb->s_blocksize_bits); } static inline int vfs_dq_prealloc_block(struct inode *inode, qsize_t nr) { - return vfs_dq_prealloc_space(inode, nr << inode->i_blkbits); + return vfs_dq_prealloc_space(inode, + nr << inode->i_sb->s_blocksize_bits); } static inline int vfs_dq_alloc_block_nodirty(struct inode *inode, qsize_t nr) { - return vfs_dq_alloc_space_nodirty(inode, nr << inode->i_blkbits); + return vfs_dq_alloc_space_nodirty(inode, + nr << inode->i_sb->s_blocksize_bits); } static inline int vfs_dq_alloc_block(struct inode *inode, qsize_t nr) { - return vfs_dq_alloc_space(inode, nr << inode->i_blkbits); -} - -static inline int vfs_dq_reserve_block(struct inode *inode, qsize_t nr) -{ - return vfs_dq_reserve_space(inode, nr << inode->i_blkbits); -} - -static inline int vfs_dq_claim_block(struct inode *inode, qsize_t nr) -{ - return vfs_dq_claim_space(inode, nr << inode->i_blkbits); -} - -static inline -void vfs_dq_release_reservation_block(struct inode *inode, qsize_t nr) -{ - vfs_dq_release_reservation_space(inode, nr << inode->i_blkbits); + return vfs_dq_alloc_space(inode, + nr << inode->i_sb->s_blocksize_bits); } static inline void vfs_dq_free_block_nodirty(struct inode *inode, qsize_t nr) { - vfs_dq_free_space_nodirty(inode, nr << inode->i_blkbits); + vfs_dq_free_space_nodirty(inode, nr << inode->i_sb->s_blocksize_bits); } static inline void vfs_dq_free_block(struct inode *inode, qsize_t nr) { - vfs_dq_free_space(inode, nr << inode->i_blkbits); + vfs_dq_free_space(inode, nr << inode->i_sb->s_blocksize_bits); } +/* + * Define uppercase equivalents for compatibility with old function names + * Can go away when we think all users have been converted (15/04/2008) + */ +#define DQUOT_INIT(inode) vfs_dq_init(inode) +#define DQUOT_DROP(inode) vfs_dq_drop(inode) +#define DQUOT_PREALLOC_SPACE_NODIRTY(inode, nr) \ + vfs_dq_prealloc_space_nodirty(inode, nr) +#define DQUOT_PREALLOC_SPACE(inode, nr) vfs_dq_prealloc_space(inode, nr) +#define DQUOT_ALLOC_SPACE_NODIRTY(inode, nr) \ + vfs_dq_alloc_space_nodirty(inode, nr) +#define DQUOT_ALLOC_SPACE(inode, nr) vfs_dq_alloc_space(inode, nr) +#define DQUOT_PREALLOC_BLOCK_NODIRTY(inode, nr) \ + vfs_dq_prealloc_block_nodirty(inode, nr) +#define DQUOT_PREALLOC_BLOCK(inode, nr) vfs_dq_prealloc_block(inode, nr) +#define DQUOT_ALLOC_BLOCK_NODIRTY(inode, nr) \ + vfs_dq_alloc_block_nodirty(inode, nr) +#define DQUOT_ALLOC_BLOCK(inode, nr) vfs_dq_alloc_block(inode, nr) +#define DQUOT_ALLOC_INODE(inode) vfs_dq_alloc_inode(inode) +#define DQUOT_FREE_SPACE_NODIRTY(inode, nr) \ + vfs_dq_free_space_nodirty(inode, nr) +#define DQUOT_FREE_SPACE(inode, nr) vfs_dq_free_space(inode, nr) +#define DQUOT_FREE_BLOCK_NODIRTY(inode, nr) \ + vfs_dq_free_block_nodirty(inode, nr) +#define DQUOT_FREE_BLOCK(inode, nr) vfs_dq_free_block(inode, nr) +#define DQUOT_FREE_INODE(inode) vfs_dq_free_inode(inode) +#define DQUOT_TRANSFER(inode, iattr) vfs_dq_transfer(inode, iattr) +#define DQUOT_SYNC(sb) vfs_dq_sync(sb) +#define DQUOT_OFF(sb, remount) vfs_dq_off(sb, remount) +#define DQUOT_ON_REMOUNT(sb) vfs_dq_quota_on_remount(sb) + #endif /* _LINUX_QUOTAOPS_ */ diff --git a/trunk/kernel/cgroup.c b/trunk/kernel/cgroup.c index c500ca7239b2..9edb5c4b79b4 100644 --- a/trunk/kernel/cgroup.c +++ b/trunk/kernel/cgroup.c @@ -1071,8 +1071,7 @@ static int cgroup_get_sb(struct file_system_type *fs_type, mutex_unlock(&cgroup_mutex); } - simple_set_mnt(mnt, sb); - return 0; + return simple_set_mnt(mnt, sb); free_cg_links: free_cg_links(&tmp_cg_links); @@ -1628,7 +1627,7 @@ static struct inode_operations cgroup_dir_inode_operations = { static int cgroup_create_file(struct dentry *dentry, int mode, struct super_block *sb) { - static const struct dentry_operations cgroup_dops = { + static struct dentry_operations cgroup_dops = { .d_iput = cgroup_diput, }; diff --git a/trunk/net/socket.c b/trunk/net/socket.c index 0b14b79c03af..af0205ff56f2 100644 --- a/trunk/net/socket.c +++ b/trunk/net/socket.c @@ -328,7 +328,7 @@ static char *sockfs_dname(struct dentry *dentry, char *buffer, int buflen) dentry->d_inode->i_ino); } -static const struct dentry_operations sockfs_dentry_operations = { +static struct dentry_operations sockfs_dentry_operations = { .d_delete = sockfs_delete_dentry, .d_dname = sockfs_dname, }; diff --git a/trunk/net/sunrpc/rpc_pipe.c b/trunk/net/sunrpc/rpc_pipe.c index 9ced0628d69c..577385a4a5dc 100644 --- a/trunk/net/sunrpc/rpc_pipe.c +++ b/trunk/net/sunrpc/rpc_pipe.c @@ -480,7 +480,7 @@ static int rpc_delete_dentry(struct dentry *dentry) return 1; } -static const struct dentry_operations rpc_dentry_operations = { +static struct dentry_operations rpc_dentry_operations = { .d_delete = rpc_delete_dentry, };