]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge branch 'drm-intel-next' of git://git.kernel.org/pub/scm/linux/kernel/git/anholt...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 27 Mar 2009 23:50:49 +0000 (16:50 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 27 Mar 2009 23:50:49 +0000 (16:50 -0700)
* 'drm-intel-next' of git://git.kernel.org/pub/scm/linux/kernel/git/anholt/drm-intel: (25 commits)
  drm/i915: Fix LVDS dither setting
  drm/i915: Check for dev->primary->master before dereference.
  drm/i915: TV detection fix
  drm/i915: TV mode_set sync up with 2D driver
  drm/i915: Fix TV get_modes to return modes count
  drm/i915: Sync crt hotplug detection with intel video driver
  drm/i915: Sync mode_valid/mode_set with intel video driver
  drm/i915: TV modes' parameters sync up with 2D driver
  agp/intel: Add support for new intel chipset.
  i915/drm: Remove two redundant agp_chipset_flushes
  drm/i915: Display fence register state in debugfs i915_gem_fence_regs node.
  drm/i915: Add information on pinning and fencing to the i915 list debug.
  drm/i915: Consolidate gem object list dumping
  drm/i915: Convert i915 proc files to seq_file and move to debugfs.
  drm: Convert proc files to seq_file and introduce debugfs
  drm/i915: Fix lock order reversal in GEM relocation entry copying.
  drm/i915: Fix lock order reversal with cliprects and cmdbuf in non-DRI2 paths.
  drm/i915: Fix lock order reversal in shmem pread path.
  drm/i915: Fix lock order reversal in shmem pwrite path.
  drm/i915: Make GEM object's page lists refcounted instead of get/free.
  ...

154 files changed:
arch/alpha/kernel/entry.S
arch/alpha/kernel/osf_sys.c
arch/ia64/ia32/ia32_entry.S
arch/ia64/kernel/perfmon.c
arch/mips/kernel/linux32.c
arch/mips/kernel/scall64-n32.S
arch/mips/kernel/scall64-o32.S
arch/parisc/kernel/syscall_table.S
arch/powerpc/include/asm/systbl.h
arch/s390/kernel/compat_wrapper.S
arch/sparc/kernel/time_64.c
arch/x86/ia32/ia32entry.S
arch/x86/ia32/sys_ia32.c
arch/x86/include/asm/ia32.h
arch/x86/include/asm/sys_ia32.h
drivers/infiniband/hw/nes/nes_nic.c
drivers/mtd/mtdsuper.c
fs/9p/v9fs_vfs.h
fs/9p/vfs_dentry.c
fs/9p/vfs_super.c
fs/Kconfig
fs/Makefile
fs/adfs/adfs.h
fs/adfs/dir.c
fs/affs/affs.h
fs/affs/amigaffs.c
fs/affs/namei.c
fs/afs/dir.c
fs/anon_inodes.c
fs/attr.c
fs/autofs/root.c
fs/autofs4/inode.c
fs/autofs4/root.c
fs/block_dev.c
fs/buffer.c
fs/cifs/cifsfs.c
fs/cifs/cifsfs.h
fs/cifs/dir.c
fs/coda/dir.c
fs/compat.c
fs/configfs/dir.c
fs/dcache.c
fs/devpts/inode.c
fs/dlm/dir.c
fs/dlm/dlm_internal.h
fs/dlm/lock.c
fs/dlm/lockspace.c
fs/dlm/lowcomms.c
fs/dlm/user.c
fs/drop_caches.c
fs/ecryptfs/dentry.c
fs/ecryptfs/ecryptfs_kernel.h
fs/ext2/balloc.c
fs/ext2/ialloc.c
fs/ext2/inode.c
fs/ext2/super.c
fs/ext2/xattr.c
fs/ext3/balloc.c
fs/ext3/ialloc.c
fs/ext3/inode.c
fs/ext3/namei.c
fs/ext3/super.c
fs/ext3/xattr.c
fs/ext4/balloc.c
fs/ext4/ext4.h
fs/ext4/ialloc.c
fs/ext4/inode.c
fs/ext4/mballoc.c
fs/ext4/namei.c
fs/ext4/super.c
fs/ext4/xattr.c
fs/fat/namei_msdos.c
fs/fat/namei_vfat.c
fs/fuse/dir.c
fs/fuse/fuse_i.h
fs/gfs2/ops_dentry.c
fs/gfs2/super.h
fs/hfs/hfs_fs.h
fs/hfs/sysdep.c
fs/hfsplus/hfsplus_fs.h
fs/hfsplus/inode.c
fs/hostfs/hostfs_kern.c
fs/hpfs/dentry.c
fs/inode.c
fs/isofs/inode.c
fs/jfs/acl.c
fs/jfs/inode.c
fs/jfs/jfs_dtree.c
fs/jfs/jfs_extent.c
fs/jfs/jfs_inode.c
fs/jfs/jfs_inode.h
fs/jfs/jfs_xtree.c
fs/jfs/namei.c
fs/jfs/xattr.c
fs/libfs.c
fs/namei.c
fs/namespace.c
fs/ncpfs/dir.c
fs/nfs/dir.c
fs/nfs/nfs4_fs.h
fs/nfsd/vfs.c
fs/notify/inotify/inotify.c
fs/ocfs2/dcache.c
fs/ocfs2/dcache.h
fs/open.c
fs/pipe.c
fs/proc/base.c
fs/proc/generic.c
fs/proc/proc_sysctl.c
fs/proc/root.c
fs/quota/Kconfig [new file with mode: 0644]
fs/quota/Makefile [new file with mode: 0644]
fs/quota/dquot.c [moved from fs/dquot.c with 85% similarity]
fs/quota/quota.c [moved from fs/quota.c with 94% similarity]
fs/quota/quota_tree.c [moved from fs/quota_tree.c with 84% similarity]
fs/quota/quota_tree.h [moved from fs/quota_tree.h with 100% similarity]
fs/quota/quota_v1.c [moved from fs/quota_v1.c with 79% similarity]
fs/quota/quota_v2.c [moved from fs/quota_v2.c with 98% similarity]
fs/quota/quotaio_v1.h [moved from fs/quotaio_v1.h with 100% similarity]
fs/quota/quotaio_v2.h [moved from fs/quotaio_v2.h with 100% similarity]
fs/ramfs/file-nommu.c
fs/reiserfs/bitmap.c
fs/reiserfs/inode.c
fs/reiserfs/namei.c
fs/reiserfs/stree.c
fs/reiserfs/super.c
fs/reiserfs/xattr.c
fs/smbfs/dir.c
fs/super.c
fs/sync.c
fs/sysfs/dir.c
fs/sysv/namei.c
fs/sysv/sysv.h
fs/ubifs/super.c
fs/udf/balloc.c
fs/udf/ialloc.c
fs/ufs/balloc.c
fs/ufs/ialloc.c
fs/ufs/inode.c
fs/ufs/namei.c
fs/ufs/super.c
fs/ufs/ufs.h
include/linux/buffer_head.h
include/linux/compat.h
include/linux/dcache.h
include/linux/fs.h
include/linux/ncp_fs.h
include/linux/nfs_fs.h
include/linux/nfs_xdr.h
include/linux/quota.h
include/linux/quotaops.h
kernel/cgroup.c
net/socket.c
net/sunrpc/rpc_pipe.c

index e4a54b615894f270b97fbf3a9ddd348e2abcae3a..b45d913a51c368881b4311d1f1887566829b09a8 100644 (file)
@@ -903,8 +903,9 @@ sys_alpha_pipe:
        stq     $26, 0($sp)
        .prologue 0
 
+       mov     $31, $17
        lda     $16, 8($sp)
-       jsr     $26, do_pipe
+       jsr     $26, do_pipe_flags
 
        ldq     $26, 0($sp)
        bne     $0, 1f
index ae41f097864b8ccc1ee49622dd96e6a88d8d4f39..42ee05981e7173d39ac6e047dabce5b46075669b 100644 (file)
@@ -46,8 +46,6 @@
 #include <asm/hwrpb.h>
 #include <asm/processor.h>
 
-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
index a46f8395e9a51857b0c0364a8b80733bd0575d64..af9405cd70e5fa36a3f786958a4fa0cc0a5cc300 100644 (file)
@@ -240,7 +240,7 @@ ia32_syscall_table:
        data8 sys_ni_syscall
        data8 sys_umask           /* 60 */
        data8 sys_chroot
-       data8 sys_ustat
+       data8 compat_sys_ustat
        data8 sys_dup2
        data8 sys_getppid
        data8 sys_getpgrp         /* 65 */
index 0e499757309bfbdab35d1233126e4259d9f42bdd..5c0f408cfd719f02ded2c58dc6ebf2b3c181c7b5 100644 (file)
@@ -2196,7 +2196,7 @@ pfmfs_delete_dentry(struct dentry *dentry)
        return 1;
 }
 
-static struct dentry_operations pfmfs_dentry_operations = {
+static const struct dentry_operations pfmfs_dentry_operations = {
        .d_delete = pfmfs_delete_dentry,
 };
 
index 49aac6e17df932a89658840302c7332a8c27f012..2a472713de8e535353ec32718b181a8405b487a6 100644 (file)
@@ -355,40 +355,6 @@ 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)
 {
index 7438e92f8a010566e183f986190b14de82e70bd7..f61d6b0e5731dadfcac24715babed10639ce97d2 100644 (file)
@@ -253,7 +253,7 @@ EXPORT(sysn32_call_table)
        PTR     compat_sys_utime                /* 6130 */
        PTR     sys_mknod
        PTR     sys_32_personality
-       PTR     sys_32_ustat
+       PTR     compat_sys_ustat
        PTR     compat_sys_statfs
        PTR     compat_sys_fstatfs              /* 6135 */
        PTR     sys_sysfs
index b0fef4ff9827610210ef3dc16d903d347491169d..60997f1f69d4e857861df014ab37e403f1d53c60 100644 (file)
@@ -265,7 +265,7 @@ sys_call_table:
        PTR     sys_olduname
        PTR     sys_umask                       /* 4060 */
        PTR     sys_chroot
-       PTR     sys_32_ustat
+       PTR     compat_sys_ustat
        PTR     sys_dup2
        PTR     sys_getppid
        PTR     sys_getpgrp                     /* 4065 */
index 303d2b647e418daab682f586565ade19e5420325..03b9a01bc16cf49340db4d69329a08338e47650f 100644 (file)
        ENTRY_OURS(newuname)
        ENTRY_SAME(umask)               /* 60 */
        ENTRY_SAME(chroot)
-       ENTRY_SAME(ustat)
+       ENTRY_COMP(ustat)
        ENTRY_SAME(dup2)
        ENTRY_SAME(getppid)
        ENTRY_SAME(getpgrp)             /* 65 */
index 72353f6070a436747817d2394c8e8f9ff67898b0..fe166491e9dcf9a821fb10be53678b48a3f3578e 100644 (file)
@@ -65,7 +65,7 @@ SYSCALL(ni_syscall)
 SYSX(sys_ni_syscall,sys_olduname, sys_olduname)
 COMPAT_SYS_SPU(umask)
 SYSCALL_SPU(chroot)
-SYSCALL(ustat)
+COMPAT_SYS(ustat)
 SYSCALL_SPU(dup2)
 SYSCALL_SPU(getppid)
 SYSCALL_SPU(getpgrp)
index 62c706eb0de6d427401a2325dbb73e6982eec6a8..87cf5a79a351c38e5dfed555fca336b3fe6e3575 100644 (file)
@@ -252,7 +252,7 @@ sys32_chroot_wrapper:
 sys32_ustat_wrapper:
        llgfr   %r2,%r2                 # dev_t
        llgtr   %r3,%r3                 # struct ustat *
-       jg      sys_ustat
+       jg      compat_sys_ustat
 
        .globl  sys32_dup2_wrapper
 sys32_dup2_wrapper:
index 642562d83ec44603dddfbc6276fcb7a2e52a211d..4ee2e48c4b392c84ca1db5870778a7d3645e24cc 100644 (file)
@@ -724,12 +724,14 @@ 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();
 
-       kstat_this_cpu.irqs[0]++;
+       desc = irq_to_desc(0);
+       kstat_incr_irqs_this_cpu(0, desc);
 
        if (unlikely(!evt->event_handler)) {
                printk(KERN_WARNING
index 5a0d76dc56a46431690702be8f745d6813db4cfc..8ef8876666b2ed5aaabcc6f21d7129fde453ca75 100644 (file)
@@ -557,7 +557,7 @@ ia32_sys_call_table:
        .quad sys32_olduname
        .quad sys_umask         /* 60 */
        .quad sys_chroot
-       .quad sys32_ustat
+       .quad compat_sys_ustat
        .quad sys_dup2
        .quad sys_getppid
        .quad sys_getpgrp               /* 65 */
index 6c0d7f6231af26e3eb3fb26821d4dbf493233fc2..efac92fd1efbc3f3a7b1fa923b0314e951249555 100644 (file)
@@ -638,28 +638,6 @@ 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)
 {
index 50ca486fd88c9468fe52b4a9fb357f192fbd6ab0..1f7e62517284618d6fd08aad123f6e34da8caa26 100644 (file)
@@ -129,13 +129,6 @@ 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__
index ffb08be2a5303405c1a5629766f84f1964018a3b..72a6dcd1299b6154562f5717c9ef751a9e287dc2 100644 (file)
@@ -70,8 +70,6 @@ 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 *);
index 8d3e4c6f237eb8b341c681557d9c07e90fe0a5f5..ecb1f6fd627693a62f7ef83b7bdcf604ae5866af 100644 (file)
@@ -1602,8 +1602,6 @@ 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;
index 00d46e137b2ab306ca3775c4f216d6016a44df37..92285d0089c278dd0e72a60f58f7a912b831f1ec 100644 (file)
@@ -81,13 +81,16 @@ static int get_sb_mtd_aux(struct file_system_type *fs_type, int flags,
 
        /* go */
        sb->s_flags |= MS_ACTIVE;
-       return simple_set_mnt(mnt, sb);
+       simple_set_mnt(mnt, sb);
+
+       return 0;
 
        /* new mountpoint for an already mounted superblock */
 already_mounted:
        DEBUG(1, "MTDSB: Device %d (\"%s\") is already mounted\n",
              mtd->index, mtd->name);
-       ret = simple_set_mnt(mnt, sb);
+       simple_set_mnt(mnt, sb);
+       ret = 0;
        goto out_put;
 
 out_error:
index c295ba786edd9082dbd9026ef2324a2d684ea1a3..f0c7de78e205b1063fa9d552617c7d17a4123997 100644 (file)
@@ -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 struct dentry_operations v9fs_dentry_operations;
-extern struct dentry_operations v9fs_cached_dentry_operations;
+extern const struct dentry_operations v9fs_dentry_operations;
+extern const 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);
index 06dcc7c4f2343ebb9cced85a8da46c880849794f..d74325295b1e43d74617d89798a8deb78ef6a5d6 100644 (file)
@@ -104,12 +104,12 @@ void v9fs_dentry_release(struct dentry *dentry)
        }
 }
 
-struct dentry_operations v9fs_cached_dentry_operations = {
+const struct dentry_operations v9fs_cached_dentry_operations = {
        .d_delete = v9fs_cached_dentry_delete,
        .d_release = v9fs_dentry_release,
 };
 
-struct dentry_operations v9fs_dentry_operations = {
+const struct dentry_operations v9fs_dentry_operations = {
        .d_delete = v9fs_dentry_delete,
        .d_release = v9fs_dentry_release,
 };
index 93212e40221ac10d39757a09cdacffb8fb922edb..5f8ab8adb5f5d7bd47fe65c61a25df8d78b82ca3 100644 (file)
@@ -168,8 +168,9 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags,
        p9stat_free(st);
        kfree(st);
 
-P9_DPRINTK(P9_DEBUG_VFS, " return simple set mount\n");
-       return simple_set_mnt(mnt, sb);
+P9_DPRINTK(P9_DEBUG_VFS, " simple set mount, return 0\n");
+       simple_set_mnt(mnt, sb);
+       return 0;
 
 release_sb:
        if (sb) {
index 93945dd0b1aed999107f55452a2f44a67077c3f5..cef8b18ceaa367b56ffcf8145cb2f24af8de7389 100644 (file)
@@ -56,61 +56,7 @@ endif # BLOCK
 
 source "fs/notify/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
-         <http://www.tldp.org/docs.html#howto>, 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/quota/Kconfig"
 
 source "fs/autofs/Kconfig"
 source "fs/autofs4/Kconfig"
index dc20db348679d9f300f68af931b4e9b3a0019752..6e82a307bcd436c6d131b67f120c4324ad34aafe 100644 (file)
@@ -51,11 +51,7 @@ 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-$(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-y                          += quota/
 
 obj-$(CONFIG_PROC_FS)          += proc/
 obj-y                          += partitions/
index 831157502d5ae58a25bcec65c9af58d5eabc871f..e0a85dbeeb887138b2389d417b2da3354af0d271 100644 (file)
@@ -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 struct dentry_operations adfs_dentry_operations;
+extern const struct dentry_operations adfs_dentry_operations;
 extern struct adfs_dir_ops adfs_f_dir_ops;
 extern struct adfs_dir_ops adfs_fplus_dir_ops;
 
index 85a30e929800aea513f28f3e7dfd6827bb39814f..e867ccf372466aaa495d360cc1605fb43a05dc95 100644 (file)
@@ -263,7 +263,7 @@ adfs_compare(struct dentry *parent, struct qstr *entry, struct qstr *name)
        return 0;
 }
 
-struct dentry_operations adfs_dentry_operations = {
+const struct dentry_operations adfs_dentry_operations = {
        .d_hash         = adfs_hash,
        .d_compare      = adfs_compare,
 };
index e9ec915f7553f1e7e821d40a7ee9671b5c9eea1b..1a2d5e3c7f4eb5120dae33137d44cd0e9ef01849 100644 (file)
@@ -199,8 +199,7 @@ 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 struct dentry_operations         affs_dentry_operations;
-extern struct dentry_operations         affs_dentry_operations_intl;
+extern const struct dentry_operations   affs_dentry_operations;
 
 static inline void
 affs_set_blocksize(struct super_block *sb, int size)
index 805573005de66614cec77f00f83593c61fa1f027..7d0f0a30f7a3670d804b9c045e4385d961e32cdb 100644 (file)
@@ -179,14 +179,18 @@ 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)
+               if (retval) {
+                       affs_unlock_dir(dir);
                        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)
+               if (retval) {
+                       affs_unlock_dir(dir);
                        goto done;
+               }
                mark_buffer_dirty_inode(bh, inode);
 
                affs_unlock_dir(dir);
index cfcf1b6cf82be05dbd9001e494c55cfa26b4b790..960d336ec694c3d1dc83c7941753a2c7199f317a 100644 (file)
@@ -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 *);
 
-struct dentry_operations affs_dentry_operations = {
+const struct dentry_operations affs_dentry_operations = {
        .d_hash         = affs_hash_dentry,
        .d_compare      = affs_compare_dentry,
 };
 
-static struct dentry_operations affs_intl_dentry_operations = {
+static const struct dentry_operations affs_intl_dentry_operations = {
        .d_hash         = affs_intl_hash_dentry,
        .d_compare      = affs_intl_compare_dentry,
 };
index 99cf390641f74ee198e5f37d53b9a821b2268f50..9bd757774c9ed0d154b7f8ec55f93db18f08c9bc 100644 (file)
@@ -62,7 +62,7 @@ const struct inode_operations afs_dir_inode_operations = {
        .setattr        = afs_setattr,
 };
 
-static struct dentry_operations afs_fs_dentry_operations = {
+static const struct dentry_operations afs_fs_dentry_operations = {
        .d_revalidate   = afs_d_revalidate,
        .d_delete       = afs_d_delete,
        .d_release      = afs_d_release,
index 3bbdb9d023767a142f8917bc793437abf586f211..1dd96d4406c09dde60b038a0eb5900606d59e18c 100644 (file)
@@ -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 struct dentry_operations anon_inodefs_dentry_operations = {
+static const struct dentry_operations anon_inodefs_dentry_operations = {
        .d_delete       = anon_inodefs_delete_dentry,
 };
 
index f4360192a9387614b090e4ee6b467c6ee9ae082d..9fe1b1bd30a808c82b1ebfbd8f644732e4f36f3c 100644 (file)
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -173,7 +173,8 @@ 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 = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0;
+                               error = vfs_dq_transfer(inode, attr) ?
+                                       -EDQUOT : 0;
                        if (!error)
                                error = inode_setattr(inode, attr);
                }
index 8aacade56956ec650daaa537e76370724277b765..4a1401cea0a1737e45b19d4d7850fe17da55282d 100644 (file)
@@ -192,7 +192,7 @@ static int autofs_revalidate(struct dentry * dentry, struct nameidata *nd)
        return 1;
 }
 
-static struct dentry_operations autofs_dentry_operations = {
+static const struct dentry_operations autofs_dentry_operations = {
        .d_revalidate   = autofs_revalidate,
 };
 
index 716e12b627b239d23176551ffec355e0813ad6dc..69c8142da8386577cba280ba13d229db16067580 100644 (file)
@@ -310,7 +310,7 @@ static struct autofs_info *autofs4_mkroot(struct autofs_sb_info *sbi)
        return ino;
 }
 
-static struct dentry_operations autofs4_sb_dentry_operations = {
+static const struct dentry_operations autofs4_sb_dentry_operations = {
        .d_release      = autofs4_dentry_release,
 };
 
index 2a41c2a7fc521fd1f5bac1043077a146ef57c417..74b1469a950452ba86f661b79c1390d03c464857 100644 (file)
@@ -349,13 +349,13 @@ void autofs4_dentry_release(struct dentry *de)
 }
 
 /* For dentries of directories in the root dir */
-static struct dentry_operations autofs4_root_dentry_operations = {
+static const struct dentry_operations autofs4_root_dentry_operations = {
        .d_revalidate   = autofs4_revalidate,
        .d_release      = autofs4_dentry_release,
 };
 
 /* For other dentries */
-static struct dentry_operations autofs4_dentry_operations = {
+static const struct dentry_operations autofs4_dentry_operations = {
        .d_revalidate   = autofs4_revalidate,
        .d_release      = autofs4_dentry_release,
 };
index b3c1efff5e1db0180c610bf0df465527587c934c..8c3c6899ccf33f433969e1b48b045a6a896b55ef 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/module.h>
 #include <linux/blkpg.h>
 #include <linux/buffer_head.h>
+#include <linux/pagevec.h>
 #include <linux/writeback.h>
 #include <linux/mpage.h>
 #include <linux/mount.h>
@@ -174,6 +175,151 @@ 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);
index 891e1c78e4f1cdf2fef0a5737983f245901371a3..a2fd743d97cb85380b5140e5d84ba9c50c383b84 100644 (file)
@@ -165,151 +165,6 @@ 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,
index 13ea53251dcf934518889696e7222286c13aefde..38491fd3871df31258d0cd77efb1ba2d74f9cf52 100644 (file)
@@ -606,7 +606,8 @@ cifs_get_sb(struct file_system_type *fs_type,
                return rc;
        }
        sb->s_flags |= MS_ACTIVE;
-       return simple_set_mnt(mnt, sb);
+       simple_set_mnt(mnt, sb);
+       return 0;
 }
 
 static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
index 2b1d28a9ee287b6b998c034c403c240b101c682e..77e190dc28835ad1b5238c14d64b46ccefef27a1 100644 (file)
@@ -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 struct dentry_operations cifs_dentry_ops;
-extern struct dentry_operations cifs_ci_dentry_ops;
+extern const struct dentry_operations cifs_dentry_ops;
+extern const struct dentry_operations cifs_ci_dentry_ops;
 
 /* Functions related to symlinks */
 extern void *cifs_follow_link(struct dentry *direntry, struct nameidata *nd);
index f9b6f68be976e062894da51dade4f78cedbdc8f1..2f35cccfcd8d202423c4e9e1434d139cf78dc084 100644 (file)
@@ -701,7 +701,7 @@ cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
        return rc;
 }     */
 
-struct dentry_operations cifs_dentry_ops = {
+const 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;
 }
 
-struct dentry_operations cifs_ci_dentry_ops = {
+const struct dentry_operations cifs_ci_dentry_ops = {
        .d_revalidate = cifs_d_revalidate,
        .d_hash = cifs_ci_hash,
        .d_compare = cifs_ci_compare,
index 75b1fa90b2cb8ee205efc96bbbb8a7c71fc9a1e1..4bb9d0a5decc2a7f168a1886a01ef72cec5a5351 100644 (file)
@@ -59,7 +59,7 @@ static int coda_return_EIO(void)
 }
 #define CODA_EIO_ERROR ((void *) (coda_return_EIO))
 
-static struct dentry_operations coda_dentry_operations =
+static const struct dentry_operations coda_dentry_operations =
 {
        .d_revalidate   = coda_dentry_revalidate,
        .d_delete       = coda_dentry_delete,
index 0949b43794a4896827dd70714d3b3b7b9a0ae6ed..5e374aad33f73a8b478677b724f65f7b0835699b 100644 (file)
@@ -378,6 +378,34 @@ out:
        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)) ||
index 8e93341f3e82048b7f0f07d4edc6cf2e654c3f93..05373db21a4e8e4a8a297b3c83fb8ef85a0cb175 100644 (file)
@@ -72,7 +72,7 @@ static int configfs_d_delete(struct dentry *dentry)
        return 1;
 }
 
-static struct dentry_operations configfs_dentry_ops = {
+static const struct dentry_operations configfs_dentry_ops = {
        .d_iput         = configfs_d_iput,
        /* simple_delete_dentry() isn't exported */
        .d_delete       = configfs_d_delete,
index 07e2d4a44bda3204c083a6e38ef79fe9b144d958..90bbd7e1b116d0ec48a07d8dab88c5086fb647d6 100644 (file)
@@ -1247,15 +1247,18 @@ struct dentry *d_add_ci(struct dentry *dentry, struct inode *inode,
        struct dentry *found;
        struct dentry *new;
 
-       /* Does a dentry matching the name exist already? */
+       /*
+        * First check if a dentry matching the name already exists,
+        * if not go ahead and create it now.
+        */
        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);
@@ -1263,61 +1266,46 @@ struct dentry *d_add_ci(struct dentry *dentry, struct inode *inode,
                }
                return new;
        }
-       /* Matching dentry exists, check if it is negative. */
+
+       /*
+        * If a matching dentry exists, and it's not negative use it.
+        *
+        * Decrement the reference count to balance the iget() done
+        * earlier on.
+        */
        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
-        * has a 'disconnected' dentry (i.e. IS_ROOT and DCACHE_DISCONNECTED),
-        * in which case d_move() that in place of the found dentry.
+        * already has a dentry.
         */
-       if (!S_ISDIR(inode->i_mode)) {
-               /* Not a directory; everything is easy. */
-               d_instantiate(found, inode);
-               return found;
-       }
        spin_lock(&dcache_lock);
-       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.
-                */
+       if (!S_ISDIR(inode->i_mode) || list_empty(&inode->i_dentry)) {
                __d_instantiate(found, inode);
                spin_unlock(&dcache_lock);
                security_d_instantiate(found, inode);
                return found;
        }
+
        /*
-        * Directory with a 'disconnected' dentry; get a reference to the
-        * 'disconnected' dentry.
+        * In case a directory already has a (disconnected) entry grab a
+        * reference to it, move it in place and use it.
         */
        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:
index bff4052b05e7003744a57e19b7d38966c7a75d71..63a4a59e4148deae2a7709b2c9cd6722d3422d2a 100644 (file)
@@ -322,177 +322,81 @@ static int compare_init_pts_sb(struct super_block *s, void *p)
 }
 
 /*
- * Safely parse the mount options in @data and update @opts.
+ * devpts_get_sb()
  *
- * 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' 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.
  *
- * Parsing of options modifies the @data making subsequent parsing
- * incorrect. So make a local copy of @data and parse it.
+ *     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.
  *
- * 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.
+ *     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: -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().
+ *     Mounts with 'newinstance' option create a new, private namespace.
  *
- *     Mounts with 'newinstance' option create a new private namespace.
+ *     NOTE:
  *
- *     But for single-mount semantics, devpts cannot use get_sb_single(),
+ *     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 get_init_pts_sb(struct file_system_type *fs_type, int flags,
-               void *data, struct vfsmount *mnt)
+static int devpts_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       struct super_block *s;
        int error;
+       struct pts_mount_opts opts;
+       struct super_block *s;
+
+       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) {
-                       up_write(&s->s_umount);
-                       deactivate_super(s);
-                       return error;
-               }
+               if (error)
+                       goto out_undo_sget;
                s->s_flags |= MS_ACTIVE;
        }
-       do_remount_sb(s, flags, data, 0);
-       return 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;
+       simple_set_mnt(mnt, s);
 
-       err = get_init_pts_sb(fs_type, flags, data, mnt);
-       if (err)
-               return err;
+       memcpy(&(DEVPTS_SB(s))->mount_opts, &opts, sizeof(opts));
 
-       err = mknod_ptmx(mnt->mnt_sb);
-       if (err) {
-               dput(mnt->mnt_sb->s_root);
-               deactivate_super(mnt->mnt_sb);
-       }
+       error = mknod_ptmx(s);
+       if (error)
+               goto out_dput;
 
-       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;
-
-       new = is_new_instance_mount(data);
-       if (new < 0)
-               return new;
+       return 0;
 
-       if (new)
-               return new_pts_mount(fs_type, flags, data, mnt);
+out_dput:
+       dput(s->s_root);
 
-       return init_pts_mount(fs_type, flags, data, mnt);
+out_undo_sget:
+       up_write(&s->s_umount);
+       deactivate_super(s);
+       return error;
 }
+
 #else
 /*
  * This supports only the legacy single-instance semantics (no
index 92969f879a177b86f8809feccd483c25697950de..858fba14aaa60712944aa2ef67102b3acc5cb071 100644 (file)
@@ -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);
 
-       write_lock(&ls->ls_dirtbl[bucket].lock);
+       spin_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:
-       write_unlock(&ls->ls_dirtbl[bucket].lock);
+       spin_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++) {
-               write_lock(&ls->ls_dirtbl[i].lock);
+               spin_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);
                }
-               write_unlock(&ls->ls_dirtbl[i].lock);
+               spin_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);
 
-       write_lock(&ls->ls_dirtbl[bucket].lock);
+       spin_lock(&ls->ls_dirtbl[bucket].lock);
        de = search_bucket(ls, name, namelen, bucket);
        if (de) {
                *r_nodeid = de->master_nodeid;
-               write_unlock(&ls->ls_dirtbl[bucket].lock);
+               spin_unlock(&ls->ls_dirtbl[bucket].lock);
                if (*r_nodeid == nodeid)
                        return -EEXIST;
                return 0;
        }
 
-       write_unlock(&ls->ls_dirtbl[bucket].lock);
+       spin_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);
 
-       write_lock(&ls->ls_dirtbl[bucket].lock);
+       spin_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;
-       write_unlock(&ls->ls_dirtbl[bucket].lock);
+       spin_unlock(&ls->ls_dirtbl[bucket].lock);
        return 0;
 }
 
index 076e86f38bc84a4a6e247b7fb184658592e7f732..d01ca0a711db15de2f1d57854b9acb875e9c63e0 100644 (file)
@@ -99,7 +99,7 @@ struct dlm_direntry {
 
 struct dlm_dirtable {
        struct list_head        list;
-       rwlock_t                lock;
+       spinlock_t              lock;
 };
 
 struct dlm_rsbtable {
index 01e7d39c5fba8d55a4fa1a4bd8f64e13d4c32a95..205ec95b347e3001b6cb4358b8c6539802d95bed 100644 (file)
@@ -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, "add overlap %x cur %d new %d count %d flags %x",
+               log_debug(ls, "addwait %x cur %d overlap %d count %d f %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, "add_to_waiters %x error %d flags %x %d %d %s",
+               log_error(ls, "addwait error %x %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,23 +863,55 @@ 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)
+static int _remove_from_waiters(struct dlm_lkb *lkb, int mstype,
+                               struct dlm_message *ms)
 {
        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? */
 
@@ -888,8 +920,8 @@ static int _remove_from_waiters(struct dlm_lkb *lkb, int mstype)
                goto out_del;
        }
 
-       log_error(ls, "remove_from_waiters lkid %x flags %x types %d %d",
-                 lkb->lkb_id, lkb->lkb_flags, mstype, lkb->lkb_wait_type);
+       log_error(ls, "remwait error %x reply %d flags %x no wait_type",
+                 lkb->lkb_id, mstype, lkb->lkb_flags);
        return -1;
 
  out_del:
@@ -899,7 +931,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, "remove_from_waiters %x reply %d give up on %d",
+               log_error(ls, "remwait error %x reply %d wait_type %d overlap",
                          lkb->lkb_id, mstype, lkb->lkb_wait_type);
                lkb->lkb_wait_count--;
                lkb->lkb_wait_type = 0;
@@ -921,7 +953,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);
+       error = _remove_from_waiters(lkb, mstype, NULL);
        mutex_unlock(&ls->ls_waiters_mutex);
        return error;
 }
@@ -936,7 +968,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);
+       error = _remove_from_waiters(lkb, ms->m_type, ms);
        if (ms != &ls->ls_stub_ms)
                mutex_unlock(&ls->ls_waiters_mutex);
        return error;
@@ -2083,6 +2115,11 @@ 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;
 }
 
@@ -2149,6 +2186,13 @@ 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:
index aa32e5f02493656ef461099a024337793437e245..cd8e2df3c295f19dbe09141e6222ff4cd9c69a56 100644 (file)
@@ -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);
-               rwlock_init(&ls->ls_dirtbl[i].lock);
+               spin_lock_init(&ls->ls_dirtbl[i].lock);
        }
 
        INIT_LIST_HEAD(&ls->ls_waiters);
index 103a5ebd1371de0c96dacc0ebbd0a47ac8b5f166..609108a83267f3cfffd9d539f29496c0e5ffc1b1 100644 (file)
@@ -2,7 +2,7 @@
 *******************************************************************************
 **
 **  Copyright (C) Sistina Software, Inc.  1997-2003  All rights reserved.
-**  Copyright (C) 2004-2007 Red Hat, Inc.  All rights reserved.
+**  Copyright (C) 2004-2009 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 it's
+ * be expanded for the cluster infrastructure then that is its
  * 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 wither TCP or SCTP as its transport layer
+ * lowcomms will choose to use either 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 shouldbe configured using a
+ * to 0 (default) for TCP or 1 for SCTP. It should be configured using a
  * cluster-wide mechanism as it must be the same on all nodes of the cluster
  * for the DLM to function.
  *
 #include <net/sock.h>
 #include <net/tcp.h>
 #include <linux/pagemap.h>
-#include <linux/idr.h>
 #include <linux/file.h>
 #include <linux/mutex.h>
 #include <linux/sctp.h>
 #include <net/sctp/user.h>
+#include <net/ipv6.h>
 
 #include "dlm_internal.h"
 #include "lowcomms.h"
@@ -60,6 +60,7 @@
 #include "config.h"
 
 #define NEEDED_RMEM (4*1024*1024)
+#define CONN_HASH_SIZE 32
 
 struct cbuf {
        unsigned int base;
@@ -114,6 +115,7 @@ 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 */
@@ -138,14 +140,37 @@ static int dlm_local_count;
 static struct workqueue_struct *recv_workqueue;
 static struct workqueue_struct *send_workqueue;
 
-static DEFINE_IDR(connections_idr);
+static struct hlist_head connection_hash[CONN_HASH_SIZE];
 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.
@@ -154,31 +179,17 @@ static struct connection *__nodeid2con(int nodeid, gfp_t alloc)
 {
        struct connection *con = NULL;
        int r;
-       int n;
 
-       con = idr_find(&connections_idr, nodeid);
+       con = __find_con(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 = 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;
-       }
+       r = nodeid_hash(nodeid);
+       hlist_add_head(&con->list, &connection_hash[r]);
 
        con->nodeid = nodeid;
        mutex_init(&con->sock_mutex);
@@ -189,19 +200,30 @@ static struct connection *__nodeid2con(int nodeid, gfp_t alloc)
 
        /* Setup action pointers for child sockets */
        if (con->nodeid) {
-               struct connection *zerocon = idr_find(&connections_idr, 0);
+               struct connection *zerocon = __find_con(0);
 
                con->connect_action = zerocon->connect_action;
                if (!con->rx_action)
                        con->rx_action = zerocon->rx_action;
        }
 
-       if (nodeid > max_nodeid)
-               max_nodeid = nodeid;
-
        return con;
 }
 
+/* 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);
+               }
+       }
+}
+
 static struct connection *nodeid2con(int nodeid, gfp_t allocation)
 {
        struct connection *con;
@@ -217,14 +239,17 @@ 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<=max_nodeid; i++) {
-               con = __nodeid2con(i, 0);
-               if (con && con->sctp_assoc == assoc_id) {
-                       mutex_unlock(&connections_lock);
-                       return con;
+
+       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;
+                       }
                }
        }
        mutex_unlock(&connections_lock);
@@ -250,8 +275,7 @@ 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;
-               memcpy(&ret6->sin6_addr, &in6->sin6_addr,
-                      sizeof(in6->sin6_addr));
+               ipv6_addr_copy(&ret6->sin6_addr, &in6->sin6_addr);
        }
 
        return 0;
@@ -376,25 +400,23 @@ 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)
 {
-       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);
-                       }
-               }
-       }
+
+       foreach_conn(sctp_init_failed_foreach);
+
        mutex_unlock(&connections_lock);
 }
 
@@ -1313,13 +1335,10 @@ out_connect:
 
 static void clean_one_writequeue(struct connection *con)
 {
-       struct list_head *list;
-       struct list_head *temp;
+       struct writequeue_entry *e, *safe;
 
        spin_lock(&con->writequeue_lock);
-       list_for_each_safe(list, temp, &con->writequeue) {
-               struct writequeue_entry *e =
-                       list_entry(list, struct writequeue_entry, list);
+       list_for_each_entry_safe(e, safe, &con->writequeue, list) {
                list_del(&e->list);
                free_entry(e);
        }
@@ -1369,14 +1388,7 @@ static void process_send_sockets(struct work_struct *work)
 /* Discard all entries on the write queues */
 static void clean_writequeues(void)
 {
-       int nodeid;
-
-       for (nodeid = 1; nodeid <= max_nodeid; nodeid++) {
-               struct connection *con = __nodeid2con(nodeid, 0);
-
-               if (con)
-                       clean_one_writequeue(con);
-       }
+       foreach_conn(clean_one_writequeue);
 }
 
 static void work_stop(void)
@@ -1406,23 +1418,29 @@ static int work_start(void)
        return 0;
 }
 
-void dlm_lowcomms_stop(void)
+static void stop_conn(struct connection *con)
 {
-       int i;
-       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)
+{
        /* Set all the flags to prevent any
           socket activity.
        */
        mutex_lock(&connections_lock);
-       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;
-               }
-       }
+       foreach_conn(stop_conn);
        mutex_unlock(&connections_lock);
 
        work_stop();
@@ -1430,25 +1448,20 @@ void dlm_lowcomms_stop(void)
        mutex_lock(&connections_lock);
        clean_writequeues();
 
-       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;
+       foreach_conn(free_conn);
+
        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) {
index 065149e84f42ed547961c19477506489d922ac01..ebce994ab0b717253a0bfa98230c80cefde397d2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006-2008 Red Hat, Inc.  All rights reserved.
+ * Copyright (C) 2006-2009 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,
-                        size_t count)
+                        int namelen)
 {
        kb->version[0] = kb32->version[0];
        kb->version[1] = kb32->version[1];
@@ -96,8 +96,7 @@ 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, count -
-                       offsetof(struct dlm_write_request32, i.lspace.name));
+               memcpy(kb->i.lspace.name, kb32->i.lspace.name, namelen);
        } else if (kb->cmd == DLM_USER_PURGE) {
                kb->i.purge.nodeid = kb32->i.purge.nodeid;
                kb->i.purge.pid = kb32->i.purge.pid;
@@ -115,8 +114,7 @@ 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, count -
-                       offsetof(struct dlm_write_request32, i.lock.name));
+               memcpy(kb->i.lock.name, kb32->i.lock.name, namelen);
        }
 }
 
@@ -539,9 +537,16 @@ 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;
-               kbuf = kmalloc(count + 1 + (sizeof(struct dlm_write_request) -
-                              sizeof(struct dlm_write_request32)), GFP_KERNEL);
+
+               /* add 1 after namelen so that the name string is terminated */
+               kbuf = kzalloc(sizeof(struct dlm_write_request) + namelen + 1,
+                              GFP_KERNEL);
                if (!kbuf) {
                        kfree(k32buf);
                        return -ENOMEM;
@@ -549,7 +554,8 @@ 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, count + 1);
+
+               compat_input(kbuf, k32buf, namelen);
                kfree(k32buf);
        }
 #endif
index 3e5637fc377962e1aaca5665f3e03d89366673e3..44d725f612cf346ec2e4d9bf2801913de393b967 100644 (file)
@@ -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))
+               if (inode->i_state & (I_FREEING|I_WILL_FREE|I_NEW))
                        continue;
                if (inode->i_mapping->nrpages == 0)
                        continue;
index 5e596583946c9de4eab193be422c93b8700815a0..2dda5ade75bc78a06461d0b62fbb9f74bde28678 100644 (file)
@@ -89,7 +89,7 @@ static void ecryptfs_d_release(struct dentry *dentry)
        return;
 }
 
-struct dentry_operations ecryptfs_dops = {
+const struct dentry_operations ecryptfs_dops = {
        .d_revalidate = ecryptfs_d_revalidate,
        .d_release = ecryptfs_d_release,
 };
index ac749d4d644fe383caca23093f43b65ffd2c9ba8..064c5820e4e50dc3ba53b320b518a9e3c4ba7caa 100644 (file)
@@ -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 struct dentry_operations ecryptfs_dops;
+extern const struct dentry_operations ecryptfs_dops;
 extern struct address_space_operations ecryptfs_aops;
 extern int ecryptfs_verbosity;
 extern unsigned int ecryptfs_message_buf_len;
index 4a29d6376081db526331f738b51dc6efe8f29e0b..7f8d2e5a7ea6d2dd8b0ec80d158bab82279408b1 100644 (file)
@@ -570,7 +570,7 @@ do_more:
 error_return:
        brelse(bitmap_bh);
        release_blocks(sb, freed);
-       DQUOT_FREE_BLOCK(inode, freed);
+       vfs_dq_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 (DQUOT_ALLOC_BLOCK(inode, num)) {
+       if (vfs_dq_alloc_block(inode, num)) {
                *errp = -EDQUOT;
                return 0;
        }
@@ -1409,7 +1409,7 @@ allocated:
 
        *errp = 0;
        brelse(bitmap_bh);
-       DQUOT_FREE_BLOCK(inode, *count-num);
+       vfs_dq_free_block(inode, *count-num);
        *count = num;
        return ret_block;
 
@@ -1420,7 +1420,7 @@ out:
         * Undo the block allocation
         */
        if (!performed_allocation)
-               DQUOT_FREE_BLOCK(inode, *count);
+               vfs_dq_free_block(inode, *count);
        brelse(bitmap_bh);
        return 0;
 }
index 66321a877e7458795616e0568c58fac83e0437fd..15387c9c17d8f77f36c7eeb053a9fcb779f15598 100644 (file)
@@ -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);
-               DQUOT_FREE_INODE(inode);
-               DQUOT_DROP(inode);
+               vfs_dq_free_inode(inode);
+               vfs_dq_drop(inode);
        }
 
        es = EXT2_SB(sb)->s_es;
@@ -586,7 +586,7 @@ got:
                goto fail_drop;
        }
 
-       if (DQUOT_ALLOC_INODE(inode)) {
+       if (vfs_dq_alloc_inode(inode)) {
                err = -EDQUOT;
                goto fail_drop;
        }
@@ -605,10 +605,10 @@ got:
        return inode;
 
 fail_free_drop:
-       DQUOT_FREE_INODE(inode);
+       vfs_dq_free_inode(inode);
 
 fail_drop:
-       DQUOT_DROP(inode);
+       vfs_dq_drop(inode);
        inode->i_flags |= S_NOQUOTA;
        inode->i_nlink = 0;
        unlock_new_inode(inode);
index 23fff2f87783f7e8856a6ba3679e2e0057d94767..b43b9556366324271165f46a996fc965fe9b5a17 100644 (file)
@@ -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 = DQUOT_TRANSFER(inode, iattr) ? -EDQUOT : 0;
+               error = vfs_dq_transfer(inode, iattr) ? -EDQUOT : 0;
                if (error)
                        return error;
        }
index 7c6e3606f0ecd0d4c4efc64d262b0184b392deaa..f983225266dc7fa2066a5db6b0e929143f603ec1 100644 (file)
@@ -1331,6 +1331,7 @@ 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;
index 987a5261cc2e8ef8a2e164c4f491b37856f14be3..7913531ec6d5d1c7c750bb13b6912d4c844fa448 100644 (file)
@@ -642,7 +642,7 @@ ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh,
                                ea_bdebug(new_bh, "reusing block");
 
                                error = -EDQUOT;
-                               if (DQUOT_ALLOC_BLOCK(inode, 1)) {
+                               if (vfs_dq_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)
-                               DQUOT_FREE_BLOCK(inode, 1);
+                               vfs_dq_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);
-                       DQUOT_FREE_BLOCK(inode, 1);
+                       vfs_dq_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);
-               DQUOT_FREE_BLOCK(inode, 1);
+               vfs_dq_free_block(inode, 1);
        }
        EXT2_I(inode)->i_file_acl = 0;
 
index 0dbf1c0484752f8108dc16b6530e60ae281c1648..225202db89746d142ecbe67db17318a423b6049e 100644 (file)
@@ -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)
-               DQUOT_FREE_BLOCK(inode, dquot_freed_blocks);
+               vfs_dq_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 (DQUOT_ALLOC_BLOCK(inode, num)) {
+       if (vfs_dq_alloc_block(inode, num)) {
                *errp = -EDQUOT;
                return 0;
        }
@@ -1714,7 +1714,7 @@ allocated:
 
        *errp = 0;
        brelse(bitmap_bh);
-       DQUOT_FREE_BLOCK(inode, *count-num);
+       vfs_dq_free_block(inode, *count-num);
        *count = num;
        return ret_block;
 
@@ -1729,7 +1729,7 @@ out:
         * Undo the block allocation
         */
        if (!performed_allocation)
-               DQUOT_FREE_BLOCK(inode, *count);
+               vfs_dq_free_block(inode, *count);
        brelse(bitmap_bh);
        return 0;
 }
index 8de6c720e510910b0278c5c806e836494d783fd2..dd13d60d524bb7d0d0a935a8f79123cc4a099ba4 100644 (file)
@@ -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.
         */
-       DQUOT_INIT(inode);
+       vfs_dq_init(inode);
        ext3_xattr_delete_inode(handle, inode);
-       DQUOT_FREE_INODE(inode);
-       DQUOT_DROP(inode);
+       vfs_dq_free_inode(inode);
+       vfs_dq_drop(inode);
 
        is_directory = S_ISDIR(inode->i_mode);
 
@@ -589,7 +589,7 @@ got:
                sizeof(struct ext3_inode) - EXT3_GOOD_OLD_INODE_SIZE : 0;
 
        ret = inode;
-       if(DQUOT_ALLOC_INODE(inode)) {
+       if (vfs_dq_alloc_inode(inode)) {
                err = -EDQUOT;
                goto fail_drop;
        }
@@ -620,10 +620,10 @@ really_out:
        return ret;
 
 fail_free_drop:
-       DQUOT_FREE_INODE(inode);
+       vfs_dq_free_inode(inode);
 
 fail_drop:
-       DQUOT_DROP(inode);
+       vfs_dq_drop(inode);
        inode->i_flags |= S_NOQUOTA;
        inode->i_nlink = 0;
        unlock_new_inode(inode);
index 05e5c2e5c0d77cb9de0d00cbf12782a7cbf86d11..4a09ff169870517b13f65e0d26507c6505e465b2 100644 (file)
@@ -3063,7 +3063,7 @@ int ext3_setattr(struct dentry *dentry, struct iattr *attr)
                        error = PTR_ERR(handle);
                        goto err_out;
                }
-               error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0;
+               error = vfs_dq_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 DQUOT_INIT so
+       /* We know that structure was already allocated during vfs_dq_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, DQUOT_ALLOC_SPACE() will always dirty the inode when blocks
+ * Also, vfs_dq_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
index 4db4ffa1edad2f54c5b5de0d8c80ee26f83bb20b..e2fc63cbba8b81e91945eee43d35c4b482f58fdc 100644 (file)
@@ -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 */
-       DQUOT_INIT(dentry->d_inode);
+       vfs_dq_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 */
-       DQUOT_INIT(dentry->d_inode);
+       vfs_dq_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)
-               DQUOT_INIT(new_dentry->d_inode);
+               vfs_dq_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);
index 4a970411a458f4534c9c4a09f0c02026a9bbc61e..9e5b8e387e1eadee90b24acca96fbc92d0f103a0 100644 (file)
@@ -707,8 +707,6 @@ 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);
@@ -723,8 +721,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     = ext3_dquot_initialize,
-       .drop           = ext3_dquot_drop,
+       .initialize     = dquot_initialize,
+       .drop           = dquot_drop,
        .alloc_space    = dquot_alloc_space,
        .alloc_inode    = dquot_alloc_inode,
        .free_space     = dquot_free_space,
@@ -1438,7 +1436,7 @@ static void ext3_orphan_cleanup (struct super_block * sb,
                }
 
                list_add(&EXT3_I(inode)->i_orphan, &EXT3_SB(sb)->s_orphan);
-               DQUOT_INIT(inode);
+               vfs_dq_init(inode);
                if (inode->i_nlink) {
                        printk(KERN_DEBUG
                                "%s: truncating inode %lu to %Ld bytes\n",
@@ -2702,7 +2700,7 @@ static int ext3_statfs (struct dentry * dentry, struct kstatfs * buf)
  * Process 1                         Process 2
  * ext3_create()                     quota_sync()
  *   journal_start()                   write_dquot()
- *   DQUOT_INIT()                        down(dqio_mutex)
+ *   vfs_dq_init()                       down(dqio_mutex)
  *     down(dqio_mutex)                    journal_start()
  *
  */
@@ -2714,44 +2712,6 @@ 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;
index 175414ac22109ef19bf0cf5841d131000cb7e6d2..83b7be849bd50745b3f60b3b4351eadc28f00aa3 100644 (file)
@@ -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;
-               DQUOT_FREE_BLOCK(inode, 1);
+               vfs_dq_free_block(inode, 1);
                ea_bdebug(bh, "refcount now=%d; releasing",
                          le32_to_cpu(BHDR(bh)->h_refcount));
                if (ce)
@@ -774,7 +774,7 @@ inserted:
                                /* The old block is released after updating
                                   the inode. */
                                error = -EDQUOT;
-                               if (DQUOT_ALLOC_BLOCK(inode, 1))
+                               if (vfs_dq_alloc_block(inode, 1))
                                        goto cleanup;
                                error = ext3_journal_get_write_access(handle,
                                                                      new_bh);
@@ -848,7 +848,7 @@ cleanup:
        return error;
 
 cleanup_dquot:
-       DQUOT_FREE_BLOCK(inode, 1);
+       vfs_dq_free_block(inode, 1);
        goto cleanup;
 
 bad_block:
index de9459b4cb943205c4bb40b442a486c657855f5e..38f40d55899c81e3f483c5237989bd68cf134db3 100644 (file)
@@ -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)
-               DQUOT_FREE_BLOCK(inode, dquot_freed_blocks);
+               vfs_dq_free_block(inode, dquot_freed_blocks);
        return;
 }
 
index b0c87dce66a32e56b40b5248a0019c380818ae5b..6083bb38057b8bca9fd18f83a871435d787f2468 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/blkdev.h>
 #include <linux/magic.h>
 #include <linux/jbd2.h>
+#include <linux/quota.h>
 #include "ext4_i.h"
 
 /*
@@ -1098,6 +1099,7 @@ 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);
index 2d2b3585ee91d91a211b18737de254e040b61dad..fb51b40e3e8f5a60960d8584815f390d71ae1124 100644 (file)
@@ -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.
         */
-       DQUOT_INIT(inode);
+       vfs_dq_init(inode);
        ext4_xattr_delete_inode(handle, inode);
-       DQUOT_FREE_INODE(inode);
-       DQUOT_DROP(inode);
+       vfs_dq_free_inode(inode);
+       vfs_dq_drop(inode);
 
        is_directory = S_ISDIR(inode->i_mode);
 
@@ -915,7 +915,7 @@ got:
        ei->i_extra_isize = EXT4_SB(sb)->s_want_extra_isize;
 
        ret = inode;
-       if (DQUOT_ALLOC_INODE(inode)) {
+       if (vfs_dq_alloc_inode(inode)) {
                err = -EDQUOT;
                goto fail_drop;
        }
@@ -956,10 +956,10 @@ really_out:
        return ret;
 
 fail_free_drop:
-       DQUOT_FREE_INODE(inode);
+       vfs_dq_free_inode(inode);
 
 fail_drop:
-       DQUOT_DROP(inode);
+       vfs_dq_drop(inode);
        inode->i_flags |= S_NOQUOTA;
        inode->i_nlink = 0;
        unlock_new_inode(inode);
index c7fed5b1874532ca17d1c1a2724f19096bda6c7e..71d3ecd5db798ce6bcab06331ca7ec4819f62ea1 100644 (file)
@@ -975,6 +975,17 @@ out:
        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
@@ -1036,8 +1047,14 @@ 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);
 }
 
 /*
@@ -1553,8 +1570,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
@@ -1570,12 +1587,23 @@ repeat:
        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;
@@ -1629,6 +1657,8 @@ 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,
@@ -4612,7 +4642,7 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
                        error = PTR_ERR(handle);
                        goto err_out;
                }
-               error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0;
+               error = vfs_dq_transfer(inode, attr) ? -EDQUOT : 0;
                if (error) {
                        ext4_journal_stop(handle);
                        return error;
@@ -4991,7 +5021,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, DQUOT_ALLOC_SPACE() will always dirty the inode when blocks
+ * Also, vfs_dq_alloc_block() 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
index 9f61e62f435f6baba02899bf9eaecfa1e10773f1..b038188bd039e8f8c2762c13318c078fd353b17a 100644 (file)
@@ -3086,9 +3086,12 @@ 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,
@@ -4544,7 +4547,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;
+       unsigned int inquota = 0;
        unsigned int reserv_blks = 0;
 
        sb = ar->inode->i_sb;
@@ -4562,9 +4565,17 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle,
                   (unsigned long long) ar->pleft,
                   (unsigned long long) ar->pright);
 
-       if (!EXT4_I(ar->inode)->i_delalloc_reserved_flag) {
-               /*
-                * With delalloc we already reserved the blocks
+       /*
+        * 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.
                 */
                while (ar->len && ext4_claim_free_blocks(sbi, ar->len)) {
                        /* let others to free the space */
@@ -4576,19 +4587,16 @@ 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) {
@@ -4654,8 +4662,8 @@ repeat:
 out2:
        kmem_cache_free(ext4_ac_cachep, ac);
 out1:
-       if (ar->len < inquota)
-               DQUOT_FREE_BLOCK(ar->inode, inquota - ar->len);
+       if (inquota && ar->len < inquota)
+               vfs_dq_free_block(ar->inode, inquota - ar->len);
 out3:
        if (!ar->len) {
                if (!EXT4_I(ar->inode)->i_delalloc_reserved_flag)
index ba702bd7910d955629d7ae049d1fb6930681d893..83410244d3ee11f483db465373665c9843df91cc 100644 (file)
@@ -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 */
-       DQUOT_INIT(dentry->d_inode);
+       vfs_dq_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 */
-       DQUOT_INIT(dentry->d_inode);
+       vfs_dq_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)
-               DQUOT_INIT(new_dentry->d_inode);
+               vfs_dq_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);
index 39d1993cfa1370c3718dffd95231660f3dc606b4..f7371a6a923d359480108517c1a3358276a42eb7 100644 (file)
@@ -926,8 +926,6 @@ 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);
@@ -942,9 +940,13 @@ 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     = ext4_dquot_initialize,
-       .drop           = ext4_dquot_drop,
+       .initialize     = dquot_initialize,
+       .drop           = 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,
@@ -1802,7 +1804,7 @@ static void ext4_orphan_cleanup(struct super_block *sb,
                }
 
                list_add(&EXT4_I(inode)->i_orphan, &EXT4_SB(sb)->s_orphan);
-               DQUOT_INIT(inode);
+               vfs_dq_init(inode);
                if (inode->i_nlink) {
                        printk(KERN_DEBUG
                                "%s: truncating inode %lu to %lld bytes\n",
@@ -3367,8 +3369,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()
- *   DQUOT_INIT()                        down(dqio_mutex)
+ *   jbd2_journal_start()                  write_dquot()
+ *   vfs_dq_init()                         down(dqio_mutex)
  *     down(dqio_mutex)                    jbd2_journal_start()
  *
  */
@@ -3380,44 +3382,6 @@ 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;
index 157ce6589c54b80cd1d8901418cc4eaed421d046..62b31c24699418235b98bbc164257db346202bdd 100644 (file)
@@ -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);
-               DQUOT_FREE_BLOCK(inode, 1);
+               vfs_dq_free_block(inode, 1);
                ea_bdebug(bh, "refcount now=%d; releasing",
                          le32_to_cpu(BHDR(bh)->h_refcount));
                if (ce)
@@ -784,7 +784,7 @@ inserted:
                                /* The old block is released after updating
                                   the inode. */
                                error = -EDQUOT;
-                               if (DQUOT_ALLOC_BLOCK(inode, 1))
+                               if (vfs_dq_alloc_block(inode, 1))
                                        goto cleanup;
                                error = ext4_journal_get_write_access(handle,
                                                                      new_bh);
@@ -860,7 +860,7 @@ cleanup:
        return error;
 
 cleanup_dquot:
-       DQUOT_FREE_BLOCK(inode, 1);
+       vfs_dq_free_block(inode, 1);
        goto cleanup;
 
 bad_block:
index 7ba03a4acbe07d7f8d426580e785f86075e1e7d0..da3f361a37ddb794bd38973bfea03548edbc3e86 100644 (file)
@@ -188,7 +188,7 @@ old_compare:
        goto out;
 }
 
-static struct dentry_operations msdos_dentry_operations = {
+static const struct dentry_operations msdos_dentry_operations = {
        .d_hash         = msdos_hash,
        .d_compare      = msdos_cmp,
 };
index 8ae32e37673c32fbee31e0a89eec705fbacf8267..a0e00e3a46e91fdaa9a881f7e11d69de671e74b4 100644 (file)
@@ -166,13 +166,13 @@ static int vfat_cmp(struct dentry *dentry, struct qstr *a, struct qstr *b)
        return 1;
 }
 
-static struct dentry_operations vfat_ci_dentry_ops = {
+static const struct dentry_operations vfat_ci_dentry_ops = {
        .d_revalidate   = vfat_revalidate_ci,
        .d_hash         = vfat_hashi,
        .d_compare      = vfat_cmpi,
 };
 
-static struct dentry_operations vfat_dentry_ops = {
+static const struct dentry_operations vfat_dentry_ops = {
        .d_revalidate   = vfat_revalidate,
        .d_hash         = vfat_hash,
        .d_compare      = vfat_cmp,
index fdff346e96fdc9dead4f9a00a081f5488fc4a9e3..06da05261e04a8a314881cee7e9e5988bc09c66a 100644 (file)
@@ -224,7 +224,7 @@ static int invalid_nodeid(u64 nodeid)
        return !nodeid || nodeid == FUSE_ROOT_ID;
 }
 
-struct dentry_operations fuse_dentry_operations = {
+const struct dentry_operations fuse_dentry_operations = {
        .d_revalidate   = fuse_dentry_revalidate,
 };
 
index 5e64b815a5a16d737e655c8deeb2729288da81fa..6fc5aedaa0d52b3d86d94bde490aa5711e47cfd1 100644 (file)
@@ -493,7 +493,7 @@ static inline u64 get_node_id(struct inode *inode)
 /** Device operations */
 extern const struct file_operations fuse_dev_operations;
 
-extern struct dentry_operations fuse_dentry_operations;
+extern const struct dentry_operations fuse_dentry_operations;
 
 /**
  * Get a filled in inode
index 5eb57b0443828e2c1c90e530e4c7e4fcb65d577e..022c66cd560638848c2a227d7bd7a56a078768ba 100644 (file)
@@ -107,7 +107,7 @@ static int gfs2_dhash(struct dentry *dentry, struct qstr *str)
        return 0;
 }
 
-struct dentry_operations gfs2_dops = {
+const struct dentry_operations gfs2_dops = {
        .d_revalidate = gfs2_drevalidate,
        .d_hash = gfs2_dhash,
 };
index 91abdbedcc86e5524efaf8012313d05222a0d303..b56413e3e40d8f86d14b5abd5aaed1c29013b4be 100644 (file)
@@ -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 struct dentry_operations gfs2_dops;
+extern const struct dentry_operations gfs2_dops;
 
 #endif /* __SUPER_DOT_H__ */
 
index 9955232fdf8c977abae64e327ca250468ee74654..052387e116716d014ff9a398a76597d6fb926131 100644 (file)
@@ -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 struct dentry_operations hfs_dentry_operations;
+extern const struct dentry_operations hfs_dentry_operations;
 
 extern int hfs_hash_dentry(struct dentry *, struct qstr *);
 extern int hfs_strcmp(const unsigned char *, unsigned int,
index 5bf89ec01cd4476ddf17d088aa7a58d8e303edc3..7478f5c219aa42336984117b937f84039af8a417 100644 (file)
@@ -31,7 +31,7 @@ static int hfs_revalidate_dentry(struct dentry *dentry, struct nameidata *nd)
        return 1;
 }
 
-struct dentry_operations hfs_dentry_operations =
+const struct dentry_operations hfs_dentry_operations =
 {
        .d_revalidate   = hfs_revalidate_dentry,
        .d_hash         = hfs_hash_dentry,
index f027a905225fc5f7a5c2dfe8b5d1e0764ec96c80..5c10d803d9df1ea10dd20b4c0c5b122b36b85e18 100644 (file)
@@ -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 struct dentry_operations hfsplus_dentry_operations;
+extern const 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 *);
index f105ee9e1cc4aad0e244e19c883e77c610954294..1bcf597c05625c8023ddf6074d9efe2aca6b8e1e 100644 (file)
@@ -137,7 +137,7 @@ const struct address_space_operations hfsplus_aops = {
        .writepages     = hfsplus_writepages,
 };
 
-struct dentry_operations hfsplus_dentry_operations = {
+const struct dentry_operations hfsplus_dentry_operations = {
        .d_hash       = hfsplus_hash_dentry,
        .d_compare    = hfsplus_compare_dentry,
 };
index 5c538e0ec14beeba40899ea9eb20b83b8446388e..fe02ad4740e76a2b4246657575d2a0f682b254f1 100644 (file)
@@ -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)
 
-int hostfs_d_delete(struct dentry *dentry)
+static int hostfs_d_delete(struct dentry *dentry)
 {
        return 1;
 }
 
-struct dentry_operations hostfs_dentry_ops = {
+static const struct dentry_operations hostfs_dentry_ops = {
        .d_delete               = hostfs_d_delete,
 };
 
index 08319126b2afa0c090b8c922350d6aaf4ad8d064..940d6d150beec4d609785c16aadb87a49b1689f7 100644 (file)
@@ -49,7 +49,7 @@ static int hpfs_compare_dentry(struct dentry *dentry, struct qstr *a, struct qst
        return 0;
 }
 
-static struct dentry_operations hpfs_dentry_operations = {
+static const struct dentry_operations hpfs_dentry_operations = {
        .d_hash         = hpfs_hash_dentry,
        .d_compare      = hpfs_compare_dentry,
 };
index 643ac43e5a5c7d6f43fe938fd4c0df6c91e2e0ce..d06d6d268de9a12c5fbe9d66bd618c293729e8e9 100644 (file)
@@ -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);
-       DQUOT_DROP(inode);
+       vfs_dq_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,6 +366,8 @@ 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);
@@ -1168,7 +1170,7 @@ void generic_delete_inode(struct inode *inode)
        if (op->delete_inode) {
                void (*delete)(struct inode *) = op->delete_inode;
                if (!is_bad_inode(inode))
-                       DQUOT_INIT(inode);
+                       vfs_dq_init(inode);
                /* Filesystems implementing their own
                 * s_op->delete_inode are required to call
                 * truncate_inode_pages and clear_inode()
index 6147ec3643a0ebd6280c478f0032fd8a0f051cd4..13d2eddd0692d74b732f6b7b31ca2fbf5fd63014 100644 (file)
@@ -114,7 +114,7 @@ static const struct super_operations isofs_sops = {
 };
 
 
-static struct dentry_operations isofs_dentry_ops[] = {
+static const struct dentry_operations isofs_dentry_ops[] = {
        {
                .d_hash         = isofs_hash,
                .d_compare      = isofs_dentry_cmp,
index d3e5c33665deceb13a0af0797a67b282129c3037..a166c1669e823823844790f43e04ee13a14a6011 100644 (file)
@@ -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 (DQUOT_TRANSFER(inode, iattr))
+               if (vfs_dq_transfer(inode, iattr))
                        return -EDQUOT;
        }
 
index b00ee9f05a0695f0a84814ae15320aaac1a58aa8..b2ae190a77ba240b04f8175d7b2e2c65aaa20b3d 100644 (file)
@@ -158,9 +158,9 @@ void jfs_delete_inode(struct inode *inode)
                /*
                 * Free the inode from the quota allocation.
                 */
-               DQUOT_INIT(inode);
-               DQUOT_FREE_INODE(inode);
-               DQUOT_DROP(inode);
+               vfs_dq_init(inode);
+               vfs_dq_free_inode(inode);
+               vfs_dq_drop(inode);
        }
 
        clear_inode(inode);
index 4dcc0581999881063ece0e2f6d745b7d52da2a5b..925871e9887baf83f8825cf9d6b04e297f945cbb 100644 (file)
@@ -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 (DQUOT_ALLOC_BLOCK(ip, sbi->nbperpage))
+               if (vfs_dq_alloc_block(ip, sbi->nbperpage))
                        goto clean_up;
                if (dbAlloc(ip, 0, sbi->nbperpage, &xaddr)) {
-                       DQUOT_FREE_BLOCK(ip, sbi->nbperpage);
+                       vfs_dq_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);
-                       DQUOT_FREE_BLOCK(ip, sbi->nbperpage);
+                       vfs_dq_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 (DQUOT_ALLOC_BLOCK(ip, n)) {
+               if (vfs_dq_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)
-               DQUOT_FREE_BLOCK(ip, quota_allocation);
+               vfs_dq_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 (DQUOT_ALLOC_BLOCK(ip, lengthPXD(pxd))) {
+       if (vfs_dq_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 (DQUOT_ALLOC_BLOCK(ip, lengthPXD(pxd))) {
+       if (vfs_dq_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. */
-       DQUOT_FREE_BLOCK(ip, xlen);
+       vfs_dq_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 */
-                               DQUOT_FREE_BLOCK(ip, xlen);
+                               vfs_dq_free_block(ip, xlen);
 
                                /* free/invalidate its buffer page */
                                discard_metapage(mp);
index 7ae1e3281de938b85432417863aa341f7483af54..169802ea07f991c85cf3e75f07ba41f701777100 100644 (file)
@@ -141,7 +141,7 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, bool abnr)
        }
 
        /* Allocate blocks to quota. */
-       if (DQUOT_ALLOC_BLOCK(ip, nxlen)) {
+       if (vfs_dq_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);
-               DQUOT_FREE_BLOCK(ip, nxlen);
+               vfs_dq_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 (DQUOT_ALLOC_BLOCK(ip, nxlen)) {
+       if (vfs_dq_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);
-                       DQUOT_FREE_BLOCK(ip, nxlen);
+                       vfs_dq_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);
-                       DQUOT_FREE_BLOCK(ip, nxlen);
+                       vfs_dq_free_block(ip, nxlen);
                        goto exit;
                }
        }
index d4d142c2edd40be792ab9bf602967ee2f61ea7f8..dc0e02159ac9e494fc99a33dcfae47ca3f5a4f5f 100644 (file)
@@ -116,7 +116,7 @@ struct inode *ialloc(struct inode *parent, umode_t mode)
        /*
         * Allocate inode to quota.
         */
-       if (DQUOT_ALLOC_INODE(inode)) {
+       if (vfs_dq_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:
-       DQUOT_DROP(inode);
+       vfs_dq_drop(inode);
        inode->i_flags |= S_NOQUOTA;
 fail_unlock:
        inode->i_nlink = 0;
index adb2fafcc54428d2542b76191e93c8ffff3bd454..1eff7db34d6357a611dbbfbff5bd64c78cac42ed 100644 (file)
@@ -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 struct dentry_operations jfs_ci_dentry_operations;
+extern const struct dentry_operations jfs_ci_dentry_operations;
 #endif                         /* _H_JFS_INODE */
index ae3acafb447b2bad3c4346bb9194b6d549dcd694..a27e26c905687b53157e2ce219eb391f91e360d7 100644 (file)
@@ -846,10 +846,10 @@ int xtInsert(tid_t tid,           /* transaction id */
                        hint = addressXAD(xad) + lengthXAD(xad) - 1;
                } else
                        hint = 0;
-               if ((rc = DQUOT_ALLOC_BLOCK(ip, xlen)))
+               if ((rc = vfs_dq_alloc_block(ip, xlen)))
                        goto out;
                if ((rc = dbAlloc(ip, hint, (s64) xlen, &xaddr))) {
-                       DQUOT_FREE_BLOCK(ip, xlen);
+                       vfs_dq_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);
-                               DQUOT_FREE_BLOCK(ip, xlen);
+                               vfs_dq_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 (DQUOT_ALLOC_BLOCK(ip, lengthPXD(pxd))) {
+       if (vfs_dq_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)
-               DQUOT_FREE_BLOCK(ip, quota_allocation);
+               vfs_dq_free_block(ip, quota_allocation);
 
        return (rc);
 }
@@ -1513,7 +1513,7 @@ xtSplitRoot(tid_t tid,
                return -EIO;
 
        /* Allocate blocks to quota. */
-       if (DQUOT_ALLOC_BLOCK(ip, lengthPXD(pxd))) {
+       if (vfs_dq_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 */
-       DQUOT_FREE_BLOCK(ip, nfreed);
+       vfs_dq_free_block(ip, nfreed);
 
        /*
         * free tlock of invalidated pages
index b4de56b851e430e74ac97cefce7b3536a372854e..514ee2edb92a9046c40661a81abf26ee1e558da6 100644 (file)
@@ -35,7 +35,7 @@
 /*
  * forward references
  */
-struct dentry_operations jfs_ci_dentry_operations;
+const 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. */
-       DQUOT_INIT(ip);
+       vfs_dq_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. */
-       DQUOT_INIT(ip);
+       vfs_dq_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. */
-               DQUOT_INIT(new_ip);
+               vfs_dq_init(new_ip);
        }
 
        /*
@@ -1595,7 +1595,7 @@ out:
        return result;
 }
 
-struct dentry_operations jfs_ci_dentry_operations =
+const struct dentry_operations jfs_ci_dentry_operations =
 {
        .d_hash = jfs_ci_hash,
        .d_compare = jfs_ci_compare,
index 9b7f2cdaae0a6655538066e104bff5e10bbcab70..61dfa8173ebccdba37a099d1b2299716b6e89218 100644 (file)
@@ -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 (DQUOT_ALLOC_BLOCK(ip, nblocks)) {
+       if (vfs_dq_alloc_block(ip, nblocks)) {
                return -EDQUOT;
        }
 
        rc = dbAlloc(ip, INOHINT(ip), nblocks, &blkno);
        if (rc) {
                /*Rollback quota allocation. */
-               DQUOT_FREE_BLOCK(ip, nblocks);
+               vfs_dq_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. */
-       DQUOT_FREE_BLOCK(ip, nblocks);
+       vfs_dq_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 (DQUOT_ALLOC_BLOCK(inode, blocks_needed))
+               if (vfs_dq_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)
-               DQUOT_FREE_BLOCK(inode, quota_allocation);
+               vfs_dq_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)
-               DQUOT_FREE_BLOCK(inode, old_blocks);
+               vfs_dq_free_block(inode, old_blocks);
 
        inode->i_ctime = CURRENT_TIME;
 
index 49b44099dabbb9cef010c2394c8ba110440edee4..4910a36f516e3081bcb61713260bb2ca637a9612 100644 (file)
@@ -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 struct dentry_operations simple_dentry_operations = {
+       static const struct dentry_operations simple_dentry_operations = {
                .d_delete = simple_delete_dentry,
        };
 
@@ -242,7 +242,8 @@ 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;
-       return simple_set_mnt(mnt, s);
+       simple_set_mnt(mnt, s);
+       return 0;
 
 Enomem:
        up_write(&s->s_umount);
index 199317642ad6d731f47dd61693a2374145f99337..d040ce11785d6acb115154da5e83a7500909df13 100644 (file)
@@ -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;
-       DQUOT_INIT(dir);
+       vfs_dq_init(dir);
        error = dir->i_op->create(dir, dentry, mode, nd);
        if (!error)
                fsnotify_create(dir, dentry);
@@ -1489,24 +1489,22 @@ int may_open(struct path *path, int acc_mode, int flag)
        if (!inode)
                return -ENOENT;
 
-       if (S_ISLNK(inode->i_mode))
+       switch (inode->i_mode & S_IFMT) {
+       case S_IFLNK:
                return -ELOOP;
-       
-       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)) {
+       case S_IFDIR:
+               if (acc_mode & MAY_WRITE)
+                       return -EISDIR;
+               break;
+       case S_IFBLK:
+       case S_IFCHR:
                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);
@@ -1552,7 +1550,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) {
-                       DQUOT_INIT(inode);
+                       vfs_dq_init(inode);
 
                        error = do_truncate(dentry, 0,
                                            ATTR_MTIME|ATTR_CTIME|ATTR_OPEN,
@@ -1563,7 +1561,7 @@ int may_open(struct path *path, int acc_mode, int flag)
                        return error;
        } else
                if (flag & FMODE_WRITE)
-                       DQUOT_INIT(inode);
+                       vfs_dq_init(inode);
 
        return 0;
 }
@@ -1946,7 +1944,7 @@ int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
        if (error)
                return error;
 
-       DQUOT_INIT(dir);
+       vfs_dq_init(dir);
        error = dir->i_op->mknod(dir, dentry, mode, dev);
        if (!error)
                fsnotify_create(dir, dentry);
@@ -2045,7 +2043,7 @@ int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
        if (error)
                return error;
 
-       DQUOT_INIT(dir);
+       vfs_dq_init(dir);
        error = dir->i_op->mkdir(dir, dentry, mode);
        if (!error)
                fsnotify_mkdir(dir, dentry);
@@ -2131,7 +2129,7 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry)
        if (!dir->i_op->rmdir)
                return -EPERM;
 
-       DQUOT_INIT(dir);
+       vfs_dq_init(dir);
 
        mutex_lock(&dentry->d_inode->i_mutex);
        dentry_unhash(dentry);
@@ -2218,7 +2216,7 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry)
        if (!dir->i_op->unlink)
                return -EPERM;
 
-       DQUOT_INIT(dir);
+       vfs_dq_init(dir);
 
        mutex_lock(&dentry->d_inode->i_mutex);
        if (d_mountpoint(dentry))
@@ -2329,7 +2327,7 @@ int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname)
        if (error)
                return error;
 
-       DQUOT_INIT(dir);
+       vfs_dq_init(dir);
        error = dir->i_op->symlink(dir, dentry, oldname);
        if (!error)
                fsnotify_create(dir, dentry);
@@ -2413,7 +2411,7 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de
                return error;
 
        mutex_lock(&inode->i_mutex);
-       DQUOT_INIT(dir);
+       vfs_dq_init(dir);
        error = dir->i_op->link(old_dentry, dir, new_dentry);
        mutex_unlock(&inode->i_mutex);
        if (!error)
@@ -2612,8 +2610,8 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
        if (!old_dir->i_op->rename)
                return -EPERM;
 
-       DQUOT_INIT(old_dir);
-       DQUOT_INIT(new_dir);
+       vfs_dq_init(old_dir);
+       vfs_dq_init(new_dir);
 
        old_name = fsnotify_oldname_init(old_dentry->d_name.name);
 
index f0e753097353b93f581d1ea6e1646df99dcf630a..0a42e0e9602766939a6ac0a2e444df2992adc3f9 100644 (file)
@@ -397,11 +397,10 @@ static void __mnt_unmake_readonly(struct vfsmount *mnt)
        spin_unlock(&vfsmount_lock);
 }
 
-int simple_set_mnt(struct vfsmount *mnt, struct super_block *sb)
+void 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);
index 07e9715b865887042b899299effe1c4f37a7e106..9c590722d87ea87fd458041815da3cd8a519b3d1 100644 (file)
@@ -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 struct dentry_operations ncp_dentry_operations =
+static const struct dentry_operations ncp_dentry_operations =
 {
        .d_revalidate   = ncp_lookup_validate,
        .d_hash         = ncp_hash_dentry,
@@ -87,7 +87,7 @@ static struct dentry_operations ncp_dentry_operations =
        .d_delete       = ncp_delete_dentry,
 };
 
-struct dentry_operations ncp_root_dentry_operations =
+const struct dentry_operations ncp_root_dentry_operations =
 {
        .d_hash         = ncp_hash_dentry,
        .d_compare      = ncp_compare_dentry,
index 672368f865cad895256d76ad6a88aa60da0e16e2..78bf72fc1db3a79fe08ae65c77960eff1326443f 100644 (file)
@@ -899,7 +899,7 @@ static void nfs_dentry_iput(struct dentry *dentry, struct inode *inode)
        iput(inode);
 }
 
-struct dentry_operations nfs_dentry_operations = {
+const 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 @@ out:
 #ifdef CONFIG_NFS_V4
 static int nfs_open_revalidate(struct dentry *, struct nameidata *);
 
-struct dentry_operations nfs4_dentry_operations = {
+const struct dentry_operations nfs4_dentry_operations = {
        .d_revalidate   = nfs_open_revalidate,
        .d_delete       = nfs_dentry_delete,
        .d_iput         = nfs_dentry_iput,
index 4e4d332043766915fd34f16625d92d345fffba39..84345deab26ff06a506dff7e4578586166437fe2 100644 (file)
@@ -179,7 +179,7 @@ struct nfs4_state_recovery_ops {
        int (*recover_lock)(struct nfs4_state *, struct file_lock *);
 };
 
-extern struct dentry_operations nfs4_dentry_operations;
+extern const struct dentry_operations nfs4_dentry_operations;
 extern const struct inode_operations nfs4_dir_inode_operations;
 
 /* inode.c */
index c165a6403df03e52219925b875ef420adcbd331a..78376b6c0236161009488e0bf4f3a2a707c3bc44 100644 (file)
@@ -356,7 +356,7 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
                        put_write_access(inode);
                        goto out_nfserr;
                }
-               DQUOT_INIT(inode);
+               vfs_dq_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;
 
-               DQUOT_INIT(inode);
+               vfs_dq_init(inode);
        }
        *filp = dentry_open(dget(dentry), mntget(fhp->fh_export->ex_path.mnt),
                            flags, cred);
index 331f2e88e284e44e373cbda23ab41a024c01c6b1..220c13f0d73d254f757636f6f03501b7fdf1b2fb 100644 (file)
@@ -379,6 +379,14 @@ 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
@@ -388,14 +396,6 @@ 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. */
index e9d7c2038c0f55c1f0cf48386a2f6eed12a2d805..7d604480557afb80a77dc7b4a106a5c9f9b6a43a 100644 (file)
@@ -455,7 +455,7 @@ out_move:
        d_move(dentry, target);
 }
 
-struct dentry_operations ocfs2_dentry_ops = {
+const struct dentry_operations ocfs2_dentry_ops = {
        .d_revalidate           = ocfs2_dentry_revalidate,
        .d_iput                 = ocfs2_dentry_iput,
 };
index d06e16c0664061d7ea7bf4bb319242a890eef68a..faa12e75f98d117a9cf2f7f0bf519a05b83c5401 100644 (file)
@@ -26,7 +26,7 @@
 #ifndef OCFS2_DCACHE_H
 #define OCFS2_DCACHE_H
 
-extern struct dentry_operations ocfs2_dentry_ops;
+extern const struct dentry_operations ocfs2_dentry_ops;
 
 struct ocfs2_dentry_lock {
        /* Use count of dentry lock */
index a3a78ceb2a2bf8c52a3b16cb7e5ca5648f710b15..75b61677daafa9fdf0317ae58afd5d017ef03c2e 100644 (file)
--- a/fs/open.c
+++ b/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) {
-               DQUOT_INIT(inode);
+               vfs_dq_init(inode);
                error = do_truncate(path.dentry, length, 0, NULL);
        }
 
index 94ad15967cf90ddc04467a093247b1da7879a3fd..4af7aa521813e89a256016329d306f8a4f6f59ec 100644 (file)
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -860,7 +860,7 @@ static char *pipefs_dname(struct dentry *dentry, char *buffer, int buflen)
                                dentry->d_inode->i_ino);
 }
 
-static struct dentry_operations pipefs_dentry_operations = {
+static const struct dentry_operations pipefs_dentry_operations = {
        .d_delete       = pipefs_delete_dentry,
        .d_dname        = pipefs_dname,
 };
@@ -1024,11 +1024,6 @@ 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.
index beaa0ce3b82e1de8fec8941584a03f3dc32a700b..aef6d55b7de6761913d78a6ab594d5ddce7119ec 100644 (file)
@@ -1545,7 +1545,7 @@ static int pid_delete_dentry(struct dentry * dentry)
        return !proc_pid(dentry->d_inode)->tasks[PIDTYPE_PID].first;
 }
 
-static struct dentry_operations pid_dentry_operations =
+static const 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 struct dentry_operations tid_fd_dentry_operations =
+static const 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 struct dentry_operations proc_base_dentry_operations =
+static const struct dentry_operations proc_base_dentry_operations =
 {
        .d_revalidate   = proc_base_revalidate,
        .d_delete       = pid_delete_dentry,
index db7fa5cab988b1679ebc80a8135cb838a167eda5..5d2989e9dcc125d17aac475df1007b86f43490fd 100644 (file)
@@ -363,7 +363,7 @@ static int proc_delete_dentry(struct dentry * dentry)
        return 1;
 }
 
-static struct dentry_operations proc_dentry_operations =
+static const struct dentry_operations proc_dentry_operations =
 {
        .d_delete       = proc_delete_dentry,
 };
index 94fcfff6863a5976965b8d4253ff3ad1ac45386b..9b1e4e9a16bfd0f1ee07f109b1964f5700c1a577 100644 (file)
@@ -7,7 +7,7 @@
 #include <linux/security.h>
 #include "internal.h"
 
-static struct dentry_operations proc_sys_dentry_operations;
+static const 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 struct dentry_operations proc_sys_dentry_operations = {
+static const struct dentry_operations proc_sys_dentry_operations = {
        .d_revalidate   = proc_sys_revalidate,
        .d_delete       = proc_sys_delete,
        .d_compare      = proc_sys_compare,
index f6299a25594e78a7527972930104924434c361c9..1e15a2b176e85a69a4657790009c58976c6dab75 100644 (file)
@@ -83,7 +83,8 @@ static int proc_get_sb(struct file_system_type *fs_type,
                ns->proc_mnt = mnt;
        }
 
-       return simple_set_mnt(mnt, sb);
+       simple_set_mnt(mnt, sb);
+       return 0;
 }
 
 static void proc_kill_sb(struct super_block *sb)
diff --git a/fs/quota/Kconfig b/fs/quota/Kconfig
new file mode 100644 (file)
index 0000000..8047e01
--- /dev/null
@@ -0,0 +1,59 @@
+#
+#  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
+         <http://www.tldp.org/docs.html#howto>, 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/fs/quota/Makefile b/fs/quota/Makefile
new file mode 100644 (file)
index 0000000..385a083
--- /dev/null
@@ -0,0 +1,14 @@
+#
+# Makefile for the Linux filesystems.
+#
+# 14 Sep 2000, Christoph Hellwig <hch@infradead.org>
+# 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
similarity index 85%
rename from fs/dquot.c
rename to fs/quota/dquot.c
index d6add0bf5ad3a9200ced2db449b0d6e1b049d146..2ca967a5ef77de2011d9896695bf80ad4f0e155b 100644 (file)
  * i_mutex on quota files is special (it's below dqio_mutex)
  */
 
-static DEFINE_SPINLOCK(dq_list_lock);
-static DEFINE_SPINLOCK(dq_state_lock);
-DEFINE_SPINLOCK(dq_data_lock);
+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 char *quotatypes[] = INITQFNAMES;
 static struct quota_format_type *quota_formats;        /* List of registered formats */
@@ -148,35 +149,46 @@ 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 = &quota_formats; *actqf && *actqf != fmt; actqf = &(*actqf)->qf_next);
+       for (actqf = &quota_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;
        }
@@ -215,6 +227,7 @@ 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)
@@ -230,7 +243,8 @@ hashfn(const struct super_block *sb, unsigned int id, int type)
  */
 static inline void insert_dquot_hash(struct dquot *dquot)
 {
-       struct hlist_head *head = dquot_hash + hashfn(dquot->dq_sb, dquot->dq_id, dquot->dq_type);
+       struct hlist_head *head;
+       head = dquot_hash + hashfn(dquot->dq_sb, dquot->dq_id, dquot->dq_type);
        hlist_add_head(&dquot->dq_hash, head);
 }
 
@@ -239,17 +253,19 @@ static inline void remove_dquot_hash(struct dquot *dquot)
        hlist_del_init(&dquot->dq_hash);
 }
 
-static inline struct dquot *find_dquot(unsigned int hashent, struct super_block *sb, unsigned int id, int type)
+static 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 NODQUOT;
+       return NULL;
 }
 
 /* Add a dquot to the tail of the free list */
@@ -309,6 +325,7 @@ 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)
@@ -345,8 +362,10 @@ 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) {
@@ -360,6 +379,7 @@ out_iolock:
        mutex_unlock(&dquot->dq_lock);
        return ret;
 }
+EXPORT_SYMBOL(dquot_acquire);
 
 /*
  *     Write dquot to disk
@@ -380,8 +400,10 @@ 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;
        }
@@ -389,6 +411,7 @@ out_sem:
        mutex_unlock(&dqopt->dqio_mutex);
        return ret;
 }
+EXPORT_SYMBOL(dquot_commit);
 
 /*
  *     Release dquot
@@ -406,8 +429,10 @@ 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;
        }
@@ -417,6 +442,7 @@ out_dqlock:
        mutex_unlock(&dquot->dq_lock);
        return ret;
 }
+EXPORT_SYMBOL(dquot_release);
 
 void dquot_destroy(struct dquot *dquot)
 {
@@ -516,6 +542,7 @@ out:
        mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
        return ret;
 }
+EXPORT_SYMBOL(dquot_scan_active);
 
 int vfs_quota_sync(struct super_block *sb, int type)
 {
@@ -533,7 +560,8 @@ 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);
@@ -563,6 +591,7 @@ 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)
@@ -672,6 +701,7 @@ we_slept:
        put_dquot_last(dquot);
        spin_unlock(&dq_list_lock);
 }
+EXPORT_SYMBOL(dqput);
 
 struct dquot *dquot_alloc(struct super_block *sb, int type)
 {
@@ -685,7 +715,7 @@ static struct dquot *get_empty_dquot(struct super_block *sb, int type)
 
        dquot = sb->dq_op->alloc_dquot(sb, type);
        if(!dquot)
-               return NODQUOT;
+               return NULL;
 
        mutex_init(&dquot->dq_lock);
        INIT_LIST_HEAD(&dquot->dq_free);
@@ -711,10 +741,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 = NODQUOT, *empty = NODQUOT;
+       struct dquot *dquot = NULL, *empty = NULL;
 
         if (!sb_has_quota_active(sb, type))
-               return NODQUOT;
+               return NULL;
 we_slept:
        spin_lock(&dq_list_lock);
        spin_lock(&dq_state_lock);
@@ -725,15 +755,17 @@ we_slept:
        }
        spin_unlock(&dq_state_lock);
 
-       if ((dquot = find_dquot(hashent, sb, id, type)) == NODQUOT) {
-               if (empty == NODQUOT) {
+       dquot = find_dquot(hashent, sb, id, type);
+       if (!dquot) {
+               if (!empty) {
                        spin_unlock(&dq_list_lock);
-                       if ((empty = get_empty_dquot(sb, type)) == NODQUOT)
+                       empty = get_empty_dquot(sb, type);
+                       if (!empty)
                                schedule();     /* Try to wait for a moment... */
                        goto we_slept;
                }
                dquot = empty;
-               empty = NODQUOT;
+               empty = NULL;
                dquot->dq_id = id;
                /* all dquots go on the inuse_list */
                put_inuse(dquot);
@@ -749,13 +781,14 @@ we_slept:
                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 and instantiate it (everything done only if needed) */
-       if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && sb->dq_op->acquire_dquot(dquot) < 0) {
+       /* Read the dquot / allocate space in quota file */
+       if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) &&
+           sb->dq_op->acquire_dquot(dquot) < 0) {
                dqput(dquot);
-               dquot = NODQUOT;
+               dquot = NULL;
                goto out;
        }
 #ifdef __DQUOT_PARANOIA
@@ -767,6 +800,7 @@ out:
 
        return dquot;
 }
+EXPORT_SYMBOL(dqget);
 
 static int dqinit_needed(struct inode *inode, int type)
 {
@@ -775,9 +809,9 @@ static int dqinit_needed(struct inode *inode, int type)
        if (IS_NOQUOTA(inode))
                return 0;
        if (type != -1)
-               return inode->i_dquot[type] == NODQUOT;
+               return !inode->i_dquot[type];
        for (cnt = 0; cnt < MAXQUOTAS; cnt++)
-               if (inode->i_dquot[cnt] == NODQUOT)
+               if (!inode->i_dquot[cnt])
                        return 1;
        return 0;
 }
@@ -789,12 +823,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);
@@ -813,7 +847,10 @@ 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)
@@ -821,22 +858,27 @@ static inline int dqput_blocks(struct dquot *dquot)
        return 0;
 }
 
-/* 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... */
+/*
+ * 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...
+ */
 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] = NODQUOT;
-       if (dquot != NODQUOT) {
+       inode->i_dquot[type] = NULL;
+       if (dquot) {
                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);
-                       list_add(&dquot->dq_free, tofree_head); /* As dquot must have currently users it can't be on the free list... */
+                       /* As dquot must have currently users it can't be on
+                        * the free list... */
+                       list_add(&dquot->dq_free, tofree_head);
                        spin_unlock(&dq_list_lock);
                        return 1;
                }
@@ -846,19 +888,22 @@ static int remove_inode_dquot_ref(struct inode *inode, int type,
        return 0;
 }
 
-/* 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 */
+/*
+ * Free list of dquots
+ * Dquots are removed from inodes and 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;
-               list_del_init(&dquot->dq_free); /* Remove dquot from the list so we won't have problems... */
+               /* Remove dquot from the list so we won't have problems... */
+               list_del_init(&dquot->dq_free);
                dqput(dquot);
        }
 }
@@ -870,6 +915,12 @@ 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);
        }
@@ -899,7 +950,29 @@ static inline void dquot_incr_space(struct dquot *dquot, qsize_t number)
        dquot->dq_dqb.dqb_curspace += number;
 }
 
-static inline void dquot_decr_inodes(struct dquot *dquot, qsize_t 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)
 {
        if (sb_dqopt(dquot->dq_sb)->flags & DQUOT_NEGATIVE_USAGE ||
            dquot->dq_dqb.dqb_curinodes >= number)
@@ -911,7 +984,7 @@ static inline void dquot_decr_inodes(struct dquot *dquot, qsize_t number)
        clear_bit(DQ_INODES_B, &dquot->dq_flags);
 }
 
-static inline void dquot_decr_space(struct dquot *dquot, qsize_t number)
+static 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)
@@ -938,7 +1011,7 @@ static int warning_issued(struct dquot *dquot, const int warntype)
 #ifdef CONFIG_PRINT_QUOTA_WARNING
 static int flag_print_warnings = 1;
 
-static inline int need_print_warning(struct dquot *dquot)
+static int need_print_warning(struct dquot *dquot)
 {
        if (!flag_print_warnings)
                return 0;
@@ -1065,13 +1138,17 @@ err_out:
        kfree_skb(skb);
 }
 #endif
-
-static inline void flush_warnings(struct dquot * const *dquots, char *warntype)
+/*
+ * 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)
 {
        int i;
 
        for (i = 0; i < MAXQUOTAS; i++)
-               if (dquots[i] != NODQUOT && warntype[i] != QUOTA_NL_NOWARN &&
+               if (dquots[i] && warntype[i] != QUOTA_NL_NOWARN &&
                    !warning_issued(dquots[i], warntype[i])) {
 #ifdef CONFIG_PRINT_QUOTA_WARNING
                        print_warning(dquots[i], warntype[i]);
@@ -1082,42 +1159,47 @@ static inline void flush_warnings(struct dquot * const *dquots, char *warntype)
                }
 }
 
-static inline char ignore_hardlimit(struct dquot *dquot)
+static int 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 &&
-          (dquot->dq_dqb.dqb_curinodes + inodes) > dquot->dq_dqb.dqb_ihardlimit &&
+           newinodes > dquot->dq_dqb.dqb_ihardlimit &&
             !ignore_hardlimit(dquot)) {
                *warntype = QUOTA_NL_IHARDWARN;
                return NO_QUOTA;
        }
 
        if (dquot->dq_dqb.dqb_isoftlimit &&
-          (dquot->dq_dqb.dqb_curinodes + inodes) > dquot->dq_dqb.dqb_isoftlimit &&
-           dquot->dq_dqb.dqb_itime && get_seconds() >= dquot->dq_dqb.dqb_itime &&
+           newinodes > 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 &&
-          (dquot->dq_dqb.dqb_curinodes + inodes) > dquot->dq_dqb.dqb_isoftlimit &&
+           newinodes > 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;
@@ -1126,13 +1208,19 @@ 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(dquot->dq_sb, dquot->dq_type) ||
+       if (!sb_has_quota_limits_enabled(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 &&
-           dquot->dq_dqb.dqb_curspace + space > dquot->dq_dqb.dqb_bhardlimit &&
+           tspace > dquot->dq_dqb.dqb_bhardlimit &&
             !ignore_hardlimit(dquot)) {
                if (!prealloc)
                        *warntype = QUOTA_NL_BHARDWARN;
@@ -1140,8 +1228,9 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *war
        }
 
        if (dquot->dq_dqb.dqb_bsoftlimit &&
-           dquot->dq_dqb.dqb_curspace + space > dquot->dq_dqb.dqb_bsoftlimit &&
-           dquot->dq_dqb.dqb_btime && get_seconds() >= dquot->dq_dqb.dqb_btime &&
+           tspace > 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;
@@ -1149,11 +1238,12 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *war
        }
 
        if (dquot->dq_dqb.dqb_bsoftlimit &&
-           dquot->dq_dqb.dqb_curspace + space > dquot->dq_dqb.dqb_bsoftlimit &&
+           tspace > 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(dquot->dq_sb)->info[dquot->dq_type].dqi_bgrace;
+                       dquot->dq_dqb.dqb_btime = get_seconds() +
+                           sb_dqopt(sb)->info[dquot->dq_type].dqi_bgrace;
                }
                else
                        /*
@@ -1168,15 +1258,18 @@ 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;
 
-       if (dquot->dq_dqb.dqb_curinodes - inodes <= dquot->dq_dqb.dqb_isoftlimit)
+       newinodes = dquot->dq_dqb.dqb_curinodes - inodes;
+       if (newinodes <= dquot->dq_dqb.dqb_isoftlimit)
                return QUOTA_NL_ISOFTBELOW;
        if (dquot->dq_dqb.dqb_curinodes >= dquot->dq_dqb.dqb_ihardlimit &&
-           dquot->dq_dqb.dqb_curinodes - inodes < dquot->dq_dqb.dqb_ihardlimit)
+           newinodes < dquot->dq_dqb.dqb_ihardlimit)
                return QUOTA_NL_IHARDBELOW;
        return QUOTA_NL_NOWARN;
 }
@@ -1203,7 +1296,7 @@ int dquot_initialize(struct inode *inode, int type)
 {
        unsigned int id = 0;
        int cnt, ret = 0;
-       struct dquot *got[MAXQUOTAS] = { NODQUOT, NODQUOT };
+       struct dquot *got[MAXQUOTAS] = { NULL, NULL };
        struct super_block *sb = inode->i_sb;
 
        /* First test before acquiring mutex - solves deadlocks when we
@@ -1236,9 +1329,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] == NODQUOT) {
+               if (!inode->i_dquot[cnt]) {
                        inode->i_dquot[cnt] = got[cnt];
-                       got[cnt] = NODQUOT;
+                       got[cnt] = NULL;
                }
        }
 out_err:
@@ -1248,6 +1341,7 @@ out_err:
                dqput(got[cnt]);
        return ret;
 }
+EXPORT_SYMBOL(dquot_initialize);
 
 /*
  *     Release all quotas referenced by inode
@@ -1260,7 +1354,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] = NODQUOT;
+               inode->i_dquot[cnt] = NULL;
        }
        up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
 
@@ -1268,6 +1362,7 @@ 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)
@@ -1284,12 +1379,13 @@ 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] != NODQUOT)
+                       if (inode->i_dquot[cnt])
                                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
@@ -1303,51 +1399,93 @@ void vfs_dq_drop(struct inode *inode)
 /*
  * This operation can block, but only after everything is updated
  */
-int dquot_alloc_space(struct inode *inode, qsize_t number, int warn)
+int __dquot_alloc_space(struct inode *inode, qsize_t number,
+                       int warn, int reserve)
 {
-       int cnt, ret = NO_QUOTA;
+       int cnt, ret = QUOTA_OK;
        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] == NODQUOT)
+               if (!inode->i_dquot[cnt])
                        continue;
-               if (check_bdq(inode->i_dquot[cnt], number, warn, warntype+cnt) == NO_QUOTA)
-                       goto warn_put_all;
+               if (check_bdq(inode->i_dquot[cnt], number, warn, warntype+cnt)
+                   == NO_QUOTA) {
+                       ret = NO_QUOTA;
+                       goto out_unlock;
+               }
        }
        for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
-               if (inode->i_dquot[cnt] == NODQUOT)
+               if (!inode->i_dquot[cnt])
                        continue;
-               dquot_incr_space(inode->i_dquot[cnt], number);
+               if (reserve)
+                       dquot_resv_space(inode->i_dquot[cnt], number);
+               else
+                       dquot_incr_space(inode->i_dquot[cnt], number);
        }
-       inode_add_bytes(inode, number);
-       ret = QUOTA_OK;
-warn_put_all:
+       if (!reserve)
+               inode_add_bytes(inode, number);
+out_unlock:
        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
@@ -1370,14 +1508,15 @@ 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] == NODQUOT)
+               if (!inode->i_dquot[cnt])
                        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] == NODQUOT)
+               if (!inode->i_dquot[cnt])
                        continue;
                dquot_incr_inodes(inode->i_dquot[cnt], number);
        }
@@ -1393,6 +1532,73 @@ warn_put_all:
        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
@@ -1418,7 +1624,7 @@ out_sub:
        }
        spin_lock(&dq_data_lock);
        for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
-               if (inode->i_dquot[cnt] == NODQUOT)
+               if (!inode->i_dquot[cnt])
                        continue;
                warntype[cnt] = info_bdq_free(inode->i_dquot[cnt], number);
                dquot_decr_space(inode->i_dquot[cnt], number);
@@ -1433,6 +1639,7 @@ out_sub:
        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
@@ -1455,7 +1662,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] == NODQUOT)
+               if (!inode->i_dquot[cnt])
                        continue;
                warntype[cnt] = info_idq_free(inode->i_dquot[cnt], number);
                dquot_decr_inodes(inode->i_dquot[cnt], number);
@@ -1469,6 +1676,20 @@ 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.
@@ -1478,7 +1699,8 @@ int dquot_free_inode(const struct inode *inode, qsize_t number)
  */
 int dquot_transfer(struct inode *inode, struct iattr *iattr)
 {
-       qsize_t space;
+       qsize_t space, cur_space;
+       qsize_t rsv_space = 0;
        struct dquot *transfer_from[MAXQUOTAS];
        struct dquot *transfer_to[MAXQUOTAS];
        int cnt, ret = QUOTA_OK;
@@ -1493,22 +1715,16 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr)
                return QUOTA_OK;
        /* Initialize the arrays */
        for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
-               transfer_from[cnt] = NODQUOT;
-               transfer_to[cnt] = NODQUOT;
+               transfer_from[cnt] = NULL;
+               transfer_to[cnt] = NULL;
                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 */
@@ -1517,10 +1733,12 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr)
                goto put_all;
        }
        spin_lock(&dq_data_lock);
-       space = inode_get_bytes(inode);
+       cur_space = inode_get_bytes(inode);
+       rsv_space = dquot_get_reserved_space(inode);
+       space = cur_space + rsv_space;
        /* Build the transfer_from list and check the limits */
        for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
-               if (transfer_to[cnt] == NODQUOT)
+               if (!transfer_to[cnt])
                        continue;
                transfer_from[cnt] = inode->i_dquot[cnt];
                if (check_idq(transfer_to[cnt], 1, warntype_to + cnt) ==
@@ -1536,7 +1754,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] == NODQUOT)
+               if (!transfer_to[cnt])
                        continue;
 
                /* Due to IO error we might not have transfer_from[] structure */
@@ -1546,11 +1764,14 @@ 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], space);
+                       dquot_decr_space(transfer_from[cnt], cur_space);
+                       dquot_free_reserved_space(transfer_from[cnt],
+                                                 rsv_space);
                }
 
                dquot_incr_inodes(transfer_to[cnt], 1);
-               dquot_incr_space(transfer_to[cnt], space);
+               dquot_incr_space(transfer_to[cnt], cur_space);
+               dquot_resv_space(transfer_to[cnt], rsv_space);
 
                inode->i_dquot[cnt] = transfer_to[cnt];
        }
@@ -1564,7 +1785,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] = NODQUOT;
+                       transfer_to[cnt] = NULL;
                }
        }
 warn_put_all:
@@ -1582,10 +1803,11 @@ over_quota:
        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] = NODQUOT;
+               transfer_from[cnt] = NULL;
        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)
@@ -1597,7 +1819,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
@@ -1612,6 +1834,7 @@ 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.
@@ -1697,8 +1920,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);
@@ -1736,10 +1959,12 @@ 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]);
                        }
@@ -1764,13 +1989,14 @@ put_inodes:
                }
        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
  */
@@ -1828,7 +2054,8 @@ 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);
@@ -1847,7 +2074,8 @@ 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);
-       if ((error = dqopt->ops[type]->read_file_info(sb, type)) < 0) {
+       error = dqopt->ops[type]->read_file_info(sb, type);
+       if (error < 0) {
                mutex_unlock(&dqopt->dqio_mutex);
                goto out_file_init;
        }
@@ -1927,6 +2155,7 @@ 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)
@@ -1944,6 +2173,7 @@ 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
@@ -1990,6 +2220,7 @@ out_lock:
 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
@@ -2019,6 +2250,7 @@ out:
        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)
@@ -2035,6 +2267,7 @@ 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)
 {
@@ -2054,7 +2287,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;
+       di->dqb_curspace = dm->dqb_curspace + dm->dqb_rsvspace;
        di->dqb_ihardlimit = dm->dqb_ihardlimit;
        di->dqb_isoftlimit = dm->dqb_isoftlimit;
        di->dqb_curinodes = dm->dqb_curinodes;
@@ -2064,18 +2297,20 @@ 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 == NODQUOT)
+       if (!dquot)
                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)
@@ -2094,7 +2329,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_curspace = di->dqb_curspace - dm->dqb_rsvspace;
                check_blim = 1;
                __set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags);
        }
@@ -2127,22 +2362,25 @@ 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);
@@ -2152,7 +2390,8 @@ 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;
@@ -2167,6 +2406,7 @@ int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *d
 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)
@@ -2188,6 +2428,7 @@ 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)
@@ -2207,7 +2448,8 @@ 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 */
@@ -2216,6 +2458,7 @@ out:
        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,
@@ -2365,43 +2608,10 @@ static int __init dquot_init(void)
 
 #ifdef CONFIG_QUOTA_NETLINK_INTERFACE
        if (genl_register_family(&quota_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);
similarity index 94%
rename from fs/quota.c
rename to fs/quota/quota.c
index d76ada914f9898f7b8c4c1435469110a35449561..b7f5a468f076d92bd6c6cc59cd955efba60e99b3 100644 (file)
@@ -20,7 +20,8 @@
 #include <linux/types.h>
 
 /* 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;
@@ -72,7 +73,8 @@ static int generic_quotactl_valid(struct super_block *sb, int type, int cmd, qid
                case Q_SETINFO:
                case Q_SETQUOTA:
                case Q_GETQUOTA:
-                       /* This is just informative test so we are satisfied without a lock */
+                       /* This is just an informative test so we are satisfied
+                        * without the lock */
                        if (!sb_has_quota_active(sb, type))
                                return -ESRCH;
        }
@@ -92,7 +94,8 @@ static int generic_quotactl_valid(struct super_block *sb, int type, int cmd, qid
 }
 
 /* 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;
@@ -142,7 +145,8 @@ static int xqm_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t i
        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;
 
@@ -180,7 +184,8 @@ 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);
        }
@@ -200,14 +205,15 @@ 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;
                }
@@ -227,7 +233,8 @@ restart:
 }
 
 /* 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;
 
@@ -235,7 +242,8 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, void
                case Q_QUOTAON: {
                        char *pathname;
 
-                       if (IS_ERR(pathname = getname(addr)))
+                       pathname = getname(addr);
+                       if (IS_ERR(pathname))
                                return PTR_ERR(pathname);
                        ret = sb->s_qcop->quota_on(sb, type, id, pathname, 0);
                        putname(pathname);
@@ -261,7 +269,8 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, void
                case Q_GETINFO: {
                        struct if_dqinfo info;
 
-                       if ((ret = sb->s_qcop->get_info(sb, type, &info)))
+                       ret = sb->s_qcop->get_info(sb, type, &info);
+                       if (ret)
                                return ret;
                        if (copy_to_user(addr, &info, sizeof(info)))
                                return -EFAULT;
@@ -277,7 +286,8 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, void
                case Q_GETQUOTA: {
                        struct if_dqblk idq;
 
-                       if ((ret = sb->s_qcop->get_dqblk(sb, type, id, &idq)))
+                       ret = sb->s_qcop->get_dqblk(sb, type, id, &idq);
+                       if (ret)
                                return ret;
                        if (copy_to_user(addr, &idq, sizeof(idq)))
                                return -EFAULT;
@@ -322,7 +332,8 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, void
                case Q_XGETQUOTA: {
                        struct fs_disk_quota fdq;
 
-                       if ((ret = sb->s_qcop->get_xquota(sb, type, id, &fdq)))
+                       ret = sb->s_qcop->get_xquota(sb, type, id, &fdq);
+                       if (ret)
                                return ret;
                        if (copy_to_user(addr, &fdq, sizeof(fdq)))
                                return -EFAULT;
@@ -341,7 +352,7 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, void
  * look up a superblock on which quota ops will be performed
  * - use the name of a block device to find the superblock thereon
  */
-static inline struct super_block *quotactl_block(const char __user *special)
+static struct super_block *quotactl_block(const char __user *special)
 {
 #ifdef CONFIG_BLOCK
        struct block_device *bdev;
similarity index 84%
rename from fs/quota_tree.c
rename to fs/quota/quota_tree.c
index 953404c95b175e3bad0cb7c010f8301493d4db11..f81f4bcfb178256070f91adcce1e977054057c59 100644 (file)
@@ -22,8 +22,6 @@ 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;
@@ -35,46 +33,42 @@ static int get_index(struct qtree_mem_dqinfo *info, qid_t id, int depth)
 }
 
 /* Number of entries in one blocks */
-static inline int qtree_dqstr_in_blk(struct qtree_mem_dqinfo *info)
+static 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 dqbuf_t getdqbuf(size_t size)
+static char *getdqbuf(size_t size)
 {
-       dqbuf_t buf = kmalloc(size, GFP_NOFS);
+       char *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 inline void freedqbuf(dqbuf_t buf)
-{
-       kfree(buf);
-}
-
-static inline ssize_t read_blk(struct qtree_mem_dqinfo *info, uint blk, dqbuf_t buf)
+static ssize_t read_blk(struct qtree_mem_dqinfo *info, uint blk, char *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, (char *)buf,
+       return sb->s_op->quota_read(sb, info->dqi_type, buf,
               info->dqi_usable_bs, blk << info->dqi_blocksize_bits);
 }
 
-static inline ssize_t write_blk(struct qtree_mem_dqinfo *info, uint blk, dqbuf_t buf)
+static ssize_t write_blk(struct qtree_mem_dqinfo *info, uint blk, char *buf)
 {
        struct super_block *sb = info->dqi_sb;
 
-       return sb->s_op->quota_write(sb, info->dqi_type, (char *)buf,
+       return sb->s_op->quota_write(sb, info->dqi_type, 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)
 {
-       dqbuf_t buf = getdqbuf(info->dqi_usable_bs);
+       char *buf = getdqbuf(info->dqi_usable_bs);
        struct qt_disk_dqdbheader *dh = (struct qt_disk_dqdbheader *)buf;
        int ret, blk;
 
@@ -98,12 +92,12 @@ static int get_free_dqblk(struct qtree_mem_dqinfo *info)
        mark_info_dirty(info->dqi_sb, info->dqi_type);
        ret = blk;
 out_buf:
-       freedqbuf(buf);
+       kfree(buf);
        return ret;
 }
 
 /* Insert empty block to the list */
-static int put_free_dqblk(struct qtree_mem_dqinfo *info, dqbuf_t buf, uint blk)
+static int put_free_dqblk(struct qtree_mem_dqinfo *info, char *buf, uint blk)
 {
        struct qt_disk_dqdbheader *dh = (struct qt_disk_dqdbheader *)buf;
        int err;
@@ -120,9 +114,10 @@ static int put_free_dqblk(struct qtree_mem_dqinfo *info, dqbuf_t buf, uint blk)
 }
 
 /* Remove given block from the list of blocks with free entries */
-static int remove_free_dqentry(struct qtree_mem_dqinfo *info, dqbuf_t buf, uint blk)
+static int remove_free_dqentry(struct qtree_mem_dqinfo *info, char *buf,
+                              uint blk)
 {
-       dqbuf_t tmpbuf = getdqbuf(info->dqi_usable_bs);
+       char *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);
@@ -153,21 +148,24 @@ static int remove_free_dqentry(struct qtree_mem_dqinfo *info, dqbuf_t buf, uint
                info->dqi_free_entry = nextblk;
                mark_info_dirty(info->dqi_sb, info->dqi_type);
        }
-       freedqbuf(tmpbuf);
+       kfree(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:
-       freedqbuf(tmpbuf);
+       kfree(tmpbuf);
        return err;
 }
 
 /* Insert given block to the beginning of list with free entries */
-static int insert_free_dqentry(struct qtree_mem_dqinfo *info, dqbuf_t buf, uint blk)
+static int insert_free_dqentry(struct qtree_mem_dqinfo *info, char *buf,
+                              uint blk)
 {
-       dqbuf_t tmpbuf = getdqbuf(info->dqi_usable_bs);
+       char *tmpbuf = getdqbuf(info->dqi_usable_bs);
        struct qt_disk_dqdbheader *dh = (struct qt_disk_dqdbheader *)buf;
        int err;
 
@@ -188,12 +186,12 @@ static int insert_free_dqentry(struct qtree_mem_dqinfo *info, dqbuf_t buf, uint
                if (err < 0)
                        goto out_buf;
        }
-       freedqbuf(tmpbuf);
+       kfree(tmpbuf);
        info->dqi_free_entry = blk;
        mark_info_dirty(info->dqi_sb, info->dqi_type);
        return 0;
 out_buf:
-       freedqbuf(tmpbuf);
+       kfree(tmpbuf);
        return err;
 }
 
@@ -215,7 +213,7 @@ static uint find_free_dqentry(struct qtree_mem_dqinfo *info,
 {
        uint blk, i;
        struct qt_disk_dqdbheader *dh;
-       dqbuf_t buf = getdqbuf(info->dqi_usable_bs);
+       char *buf = getdqbuf(info->dqi_usable_bs);
        char *ddquot;
 
        *err = 0;
@@ -233,11 +231,12 @@ static uint find_free_dqentry(struct qtree_mem_dqinfo *info,
                blk = get_free_dqblk(info);
                if ((int)blk < 0) {
                        *err = blk;
-                       freedqbuf(buf);
+                       kfree(buf);
                        return 0;
                }
                memset(buf, 0, info->dqi_usable_bs);
-               /* This is enough as block is already zeroed and entry list is empty... */
+               /* This is enough as the block is already zeroed and the entry
+                * list is empty... */
                info->dqi_free_entry = blk;
                mark_info_dirty(dquot->dq_sb, dquot->dq_type);
        }
@@ -253,9 +252,12 @@ static uint find_free_dqentry(struct qtree_mem_dqinfo *info,
        }
        le16_add_cpu(&dh->dqdh_entries, 1);
        /* Find free structure in block */
-       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);
+       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;
+       }
 #ifdef __QUOTA_QT_PARANOIA
        if (i == qtree_dqstr_in_blk(info)) {
                printk(KERN_ERR "VFS: find_free_dqentry(): Data block full "
@@ -273,10 +275,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;
-       freedqbuf(buf);
+       kfree(buf);
        return blk;
 out_buf:
-       freedqbuf(buf);
+       kfree(buf);
        return 0;
 }
 
@@ -284,7 +286,7 @@ out_buf:
 static int do_insert_tree(struct qtree_mem_dqinfo *info, struct dquot *dquot,
                          uint *treeblk, int depth)
 {
-       dqbuf_t buf = getdqbuf(info->dqi_usable_bs);
+       char *buf = getdqbuf(info->dqi_usable_bs);
        int ret = 0, newson = 0, newact = 0;
        __le32 *ref;
        uint newblk;
@@ -333,7 +335,7 @@ static int do_insert_tree(struct qtree_mem_dqinfo *info, struct dquot *dquot,
                put_free_dqblk(info, buf, *treeblk);
        }
 out_buf:
-       freedqbuf(buf);
+       kfree(buf);
        return ret;
 }
 
@@ -346,14 +348,15 @@ 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;
-       dqbuf_t ddquot = getdqbuf(info->dqi_entry_size);
+       char *ddquot = getdqbuf(info->dqi_entry_size);
 
        if (!ddquot)
                return -ENOMEM;
@@ -364,15 +367,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);
-                       freedqbuf(ddquot);
+                       kfree(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, (char *)ddquot,
-                                       info->dqi_entry_size, dquot->dq_off);
+       ret = sb->s_op->quota_write(sb, type, 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);
@@ -382,7 +385,7 @@ int qtree_write_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot)
                ret = 0;
        }
        dqstats.writes++;
-       freedqbuf(ddquot);
+       kfree(ddquot);
 
        return ret;
 }
@@ -393,7 +396,7 @@ static int free_dqentry(struct qtree_mem_dqinfo *info, struct dquot *dquot,
                        uint blk)
 {
        struct qt_disk_dqdbheader *dh;
-       dqbuf_t buf = getdqbuf(info->dqi_usable_bs);
+       char *buf = getdqbuf(info->dqi_usable_bs);
        int ret = 0;
 
        if (!buf)
@@ -444,7 +447,7 @@ static int free_dqentry(struct qtree_mem_dqinfo *info, struct dquot *dquot,
        }
        dquot->dq_off = 0;      /* Quota is now unattached */
 out_buf:
-       freedqbuf(buf);
+       kfree(buf);
        return ret;
 }
 
@@ -452,7 +455,7 @@ out_buf:
 static int remove_tree(struct qtree_mem_dqinfo *info, struct dquot *dquot,
                       uint *blk, int depth)
 {
-       dqbuf_t buf = getdqbuf(info->dqi_usable_bs);
+       char *buf = getdqbuf(info->dqi_usable_bs);
        int ret = 0;
        uint newblk;
        __le32 *ref = (__le32 *)buf;
@@ -475,9 +478,8 @@ 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) {
@@ -491,7 +493,7 @@ static int remove_tree(struct qtree_mem_dqinfo *info, struct dquot *dquot,
                }
        }
 out_buf:
-       freedqbuf(buf);
+       kfree(buf);
        return ret;
 }
 
@@ -510,7 +512,7 @@ EXPORT_SYMBOL(qtree_delete_dquot);
 static loff_t find_block_dqentry(struct qtree_mem_dqinfo *info,
                                 struct dquot *dquot, uint blk)
 {
-       dqbuf_t buf = getdqbuf(info->dqi_usable_bs);
+       char *buf = getdqbuf(info->dqi_usable_bs);
        loff_t ret = 0;
        int i;
        char *ddquot;
@@ -522,9 +524,12 @@ 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;
        }
-       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);
+       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;
+       }
        if (i == qtree_dqstr_in_blk(info)) {
                printk(KERN_ERR "VFS: Quota for id %u referenced "
                  "but not present.\n", dquot->dq_id);
@@ -535,7 +540,7 @@ static loff_t find_block_dqentry(struct qtree_mem_dqinfo *info,
                  qt_disk_dqdbheader) + i * info->dqi_entry_size;
        }
 out_buf:
-       freedqbuf(buf);
+       kfree(buf);
        return ret;
 }
 
@@ -543,7 +548,7 @@ out_buf:
 static loff_t find_tree_dqentry(struct qtree_mem_dqinfo *info,
                                struct dquot *dquot, uint blk, int depth)
 {
-       dqbuf_t buf = getdqbuf(info->dqi_usable_bs);
+       char *buf = getdqbuf(info->dqi_usable_bs);
        loff_t ret = 0;
        __le32 *ref = (__le32 *)buf;
 
@@ -563,7 +568,7 @@ static loff_t find_tree_dqentry(struct qtree_mem_dqinfo *info,
        else
                ret = find_block_dqentry(info, dquot, blk);
 out_buf:
-       freedqbuf(buf);
+       kfree(buf);
        return ret;
 }
 
@@ -579,7 +584,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;
-       dqbuf_t ddquot;
+       char *ddquot;
        int ret = 0;
 
 #ifdef __QUOTA_QT_PARANOIA
@@ -607,8 +612,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, (char *)ddquot,
-                                  info->dqi_entry_size, dquot->dq_off);
+       ret = sb->s_op->quota_read(sb, type, ddquot, info->dqi_entry_size,
+                                  dquot->dq_off);
        if (ret != info->dqi_entry_size) {
                if (ret >= 0)
                        ret = -EIO;
@@ -616,7 +621,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));
-               freedqbuf(ddquot);
+               kfree(ddquot);
                goto out;
        }
        spin_lock(&dq_data_lock);
@@ -627,7 +632,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);
-       freedqbuf(ddquot);
+       kfree(ddquot);
 out:
        dqstats.reads++;
        return ret;
@@ -638,7 +643,8 @@ 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;
 }
similarity index 100%
rename from fs/quota_tree.h
rename to fs/quota/quota_tree.h
similarity index 79%
rename from fs/quota_v1.c
rename to fs/quota/quota_v1.c
index b4af1c69ad16fb1522d14a06f5810a5b75c350d4..0edcf42b177801c48a11d32b7e8ccb6c48fcb025 100644 (file)
@@ -62,11 +62,14 @@ 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++;
 
@@ -81,13 +84,16 @@ 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);
@@ -130,15 +136,20 @@ 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 */
 }
 
@@ -148,7 +159,9 @@ static int v1_read_file_info(struct super_block *sb, int type)
        struct v1_disk_dqblk dqblk;
        int ret;
 
-       if ((ret = sb->s_op->quota_read(sb, type, (char *)&dqblk, sizeof(struct v1_disk_dqblk), v1_dqoff(0))) != sizeof(struct v1_disk_dqblk)) {
+       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 >= 0)
                        ret = -EIO;
                goto out;
@@ -157,8 +170,10 @@ 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;
 }
@@ -170,8 +185,9 @@ static int v1_write_file_info(struct super_block *sb, int type)
        int ret;
 
        dqopt->info[type].dqi_flags &= ~DQF_INFO_DIRTY;
-       if ((ret = sb->s_op->quota_read(sb, type, (char *)&dqblk,
-           sizeof(struct v1_disk_dqblk), v1_dqoff(0))) != sizeof(struct v1_disk_dqblk)) {
+       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 >= 0)
                        ret = -EIO;
                goto out;
similarity index 98%
rename from fs/quota_v2.c
rename to fs/quota/quota_v2.c
index b618b563635c6322e63be9fa00c70d0d0ad7f5b6..a5475fb1ae4478b62a02b9aae42d82a99a478bad 100644 (file)
@@ -54,7 +54,8 @@ 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);
similarity index 100%
rename from fs/quotaio_v1.h
rename to fs/quota/quotaio_v1.h
similarity index 100%
rename from fs/quotaio_v2.h
rename to fs/quota/quotaio_v2.h
index 5d7c7ececa64a3345eb9a2632a660e695a9a73cc..995ef1d6686cf38348af80da2083eb0c90bcf2ca 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/string.h>
 #include <linux/backing-dev.h>
 #include <linux/ramfs.h>
-#include <linux/quotaops.h>
 #include <linux/pagevec.h>
 #include <linux/mman.h>
 
@@ -205,11 +204,6 @@ 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);
index 4646caa60455c4666789242f40c245fdd9cc3ab0..f32d1425cc9fe58957906967a4f666009e97397f 100644 (file)
@@ -430,7 +430,7 @@ static void _reiserfs_free_block(struct reiserfs_transaction_handle *th,
 
        journal_mark_dirty(th, s, sbh);
        if (for_unformatted)
-               DQUOT_FREE_BLOCK_NODIRTY(inode, 1);
+               vfs_dq_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 =
-                   DQUOT_ALLOC_BLOCK_NODIRTY(hint->inode, amount_needed);
+                   vfs_dq_alloc_block_nodirty(hint->inode, amount_needed);
                if (quota_ret)  /* Quota exceeded? */
                        return QUOTA_EXCEEDED;
                if (hint->preallocate && hint->prealloc_size) {
@@ -1064,8 +1064,7 @@ 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 =
-                           DQUOT_PREALLOC_BLOCK_NODIRTY(hint->inode,
+                       quota_ret = vfs_dq_prealloc_block_nodirty(hint->inode,
                                                         hint->prealloc_size);
                        if (quota_ret)
                                hint->preallocate = hint->prealloc_size = 0;
@@ -1098,7 +1097,10 @@ static inline int blocknrs_and_prealloc_arrays_from_search_start
                                               nr_allocated,
                                               hint->inode->i_uid);
 #endif
-                               DQUOT_FREE_BLOCK_NODIRTY(hint->inode, amount_needed + hint->prealloc_size - nr_allocated);      /* Free not allocated blocks */
+                               /* Free not allocated blocks */
+                               vfs_dq_free_block_nodirty(hint->inode,
+                                       amount_needed + hint->prealloc_size -
+                                       nr_allocated);
                        }
                        while (nr_allocated--)
                                reiserfs_free_block(hint->th, hint->inode,
@@ -1129,7 +1131,7 @@ static inline int blocknrs_and_prealloc_arrays_from_search_start
                               REISERFS_I(hint->inode)->i_prealloc_count,
                               hint->inode->i_uid);
 #endif
-               DQUOT_FREE_BLOCK_NODIRTY(hint->inode, amount_needed +
+               vfs_dq_free_block_nodirty(hint->inode, amount_needed +
                                         hint->prealloc_size - nr_allocated -
                                         REISERFS_I(hint->inode)->
                                         i_prealloc_count);
index 55fce92cdf18f4cfc58241d3c48ef76fa04f340e..823227a7662a4eb57d1dcd62093f4786302e6a85 100644 (file)
@@ -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) 
-                       DQUOT_FREE_INODE(inode);
+                       vfs_dq_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 (DQUOT_ALLOC_INODE(inode)) {
+       if (vfs_dq_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 */
-       DQUOT_FREE_INODE(inode);
+       vfs_dq_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 */
-       DQUOT_DROP(inode);
+       vfs_dq_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 =
-                                   DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0;
+                                   vfs_dq_transfer(inode, attr) ? -EDQUOT : 0;
                                if (error) {
                                        journal_end(&th, inode->i_sb,
                                                    jbegin_count);
index 738967f6c8eec38229c30935dfb028eb120f66d1..639d635d9d4ba3a89ab07f43d5f2cf084a0b9671 100644 (file)
@@ -555,7 +555,7 @@ static int reiserfs_add_entry(struct reiserfs_transaction_handle *th,
 */
 static int drop_new_inode(struct inode *inode)
 {
-       DQUOT_DROP(inode);
+       vfs_dq_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.  
-** DQUOT_INIT needs lots of credits so it's better to have it
+** vfs_dq_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();
        }
-       DQUOT_INIT(inode);
+       vfs_dq_init(inode);
        return 0;
 }
 
index abbc64dcc8d453cd8bd2281e382c85c37bd4fbf6..73aaa33f6735661fe7932843faada42866663efc 100644 (file)
@@ -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
-       DQUOT_FREE_SPACE_NODIRTY(p_s_inode, quota_cut_bytes);
+       vfs_dq_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
-                               DQUOT_FREE_SPACE_NODIRTY(inode,
+                               vfs_dq_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
-       DQUOT_FREE_SPACE_NODIRTY(p_s_inode, quota_cut_bytes);
+       vfs_dq_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 (DQUOT_ALLOC_SPACE_NODIRTY(inode, n_pasted_size)) {
+       if (vfs_dq_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
-       DQUOT_FREE_SPACE_NODIRTY(inode, n_pasted_size);
+       vfs_dq_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 (DQUOT_ALLOC_SPACE_NODIRTY(inode, quota_bytes)) {
+               if (vfs_dq_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)
-               DQUOT_FREE_SPACE_NODIRTY(inode, quota_bytes);
+               vfs_dq_free_space_nodirty(inode, quota_bytes);
        return retval;
 }
index f3c820b758296179be10796a51a47ff3242494ac..5dbafb7394015aafbaf04bbdb00d0461c6941c90 100644 (file)
@@ -250,7 +250,7 @@ static int finish_unfinished(struct super_block *s)
                        retval = remove_save_link_only(s, &save_link_key, 0);
                        continue;
                }
-               DQUOT_INIT(inode);
+               vfs_dq_init(inode);
 
                if (truncate && S_ISDIR(inode->i_mode)) {
                        /* We got a truncate request for a dir which is impossible.
@@ -629,8 +629,6 @@ 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 *);
@@ -639,8 +637,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 = reiserfs_dquot_initialize,
-       .drop = reiserfs_dquot_drop,
+       .initialize = dquot_initialize,
+       .drop = dquot_drop,
        .alloc_space = dquot_alloc_space,
        .alloc_inode = dquot_alloc_inode,
        .free_space = dquot_free_space,
@@ -1896,58 +1894,6 @@ 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;
index ad92461cbfc3cadb5b2dcbb32725f108cc0f08a9..ae881ccd2f03472c24ba2aee911377787237ff84 100644 (file)
@@ -1136,7 +1136,7 @@ xattr_lookup_poison(struct dentry *dentry, struct qstr *q1, struct qstr *name)
        return 1;
 }
 
-static struct dentry_operations xattr_lookup_poison_ops = {
+static const struct dentry_operations xattr_lookup_poison_ops = {
        .d_compare = xattr_lookup_poison,
 };
 
index e7ddd0328ddc79ce22f95896ba3dd063d275b73e..3e4803b4427e92e3fb4617ab278e4cc30902e52c 100644 (file)
@@ -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 struct dentry_operations smbfs_dentry_operations =
+static const struct dentry_operations smbfs_dentry_operations =
 {
        .d_revalidate   = smb_lookup_validate,
        .d_hash         = smb_hash_dentry,
@@ -285,7 +285,7 @@ static struct dentry_operations smbfs_dentry_operations =
        .d_delete       = smb_delete_dentry,
 };
 
-static struct dentry_operations smbfs_dentry_operations_case =
+static const struct dentry_operations smbfs_dentry_operations_case =
 {
        .d_revalidate   = smb_lookup_validate,
        .d_delete       = smb_delete_dentry,
index dd4acb158b5e6cee3c4b194c0934bebf994c137c..2ba481518ba784ec82cbe7c83fbb3801f1f17186 100644 (file)
@@ -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);
-               DQUOT_OFF(s, 0);
+               vfs_dq_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);
-       DQUOT_SYNC(sb);
+       vfs_dq_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 = DQUOT_OFF(sb, 1);
+               retval = vfs_dq_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)
-               DQUOT_ON_REMOUNT(sb);
+               vfs_dq_quota_on_remount(sb);
        return 0;
 }
 
@@ -838,7 +838,8 @@ int get_sb_bdev(struct file_system_type *fs_type,
                bdev->bd_super = s;
        }
 
-       return simple_set_mnt(mnt, s);
+       simple_set_mnt(mnt, s);
+       return 0;
 
 error_s:
        error = PTR_ERR(s);
@@ -884,7 +885,8 @@ int get_sb_nodev(struct file_system_type *fs_type,
                return error;
        }
        s->s_flags |= MS_ACTIVE;
-       return simple_set_mnt(mnt, s);
+       simple_set_mnt(mnt, s);
+       return 0;
 }
 
 EXPORT_SYMBOL(get_sb_nodev);
@@ -916,7 +918,8 @@ int get_sb_single(struct file_system_type *fs_type,
                s->s_flags |= MS_ACTIVE;
        }
        do_remount_sb(s, flags, data, 0);
-       return simple_set_mnt(mnt, s);
+       simple_set_mnt(mnt, s);
+       return 0;
 }
 
 EXPORT_SYMBOL(get_sb_single);
index ec95a69d17aa73e058bedd5c61e42d23f87a4f91..7abc65fbf21df8455400e9757751f8069cd29f28 100644 (file)
--- a/fs/sync.c
+++ b/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 */
-       DQUOT_SYNC(NULL);
+       vfs_dq_sync(NULL);
        sync_supers();          /* Write the superblocks */
        sync_filesystems(0);    /* Start syncing the filesystems */
        sync_filesystems(wait); /* Waitingly sync the filesystems */
index 66aeb4fff0c32372968cfe3ac63f0ad0a5f00765..d88d0fac9fa5f185afd13b1f36b11f58baec672d 100644 (file)
@@ -302,7 +302,7 @@ static void sysfs_d_iput(struct dentry * dentry, struct inode * inode)
        iput(inode);
 }
 
-static struct dentry_operations sysfs_dentry_ops = {
+static const struct dentry_operations sysfs_dentry_ops = {
        .d_iput         = sysfs_d_iput,
 };
 
index a1f1ef33e81c4c5584a86630ca1bca637b078fea..33e047b59b8d659975d6c325835f0d11a2df27d4 100644 (file)
@@ -38,7 +38,7 @@ static int sysv_hash(struct dentry *dentry, struct qstr *qstr)
        return 0;
 }
 
-struct dentry_operations sysv_dentry_operations = {
+const struct dentry_operations sysv_dentry_operations = {
        .d_hash         = sysv_hash,
 };
 
index 38ebe3f85b3d092059ae81f7ad3ad6ce2db78208..5784a318c8836e53cd0728087156f318a357c6ff 100644 (file)
@@ -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 struct dentry_operations sysv_dentry_operations;
+extern const struct dentry_operations sysv_dentry_operations;
 
 
 enum {
index 1182b66a5491443ac725504ec3bd7e3bf0b0dc30..c5c98355459a5fcfab9312b3719e3695c440aadd 100644 (file)
@@ -2034,7 +2034,8 @@ 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);
 
-       return simple_set_mnt(mnt, sb);
+       simple_set_mnt(mnt, sb);
+       return 0;
 
 out_deact:
        up_write(&sb->s_umount);
index 1b809bd494bd098a0a7855ba10f300f66a08d46a..2bb788a2acb16bf24ab25a708390e58842f06116 100644 (file)
@@ -206,7 +206,7 @@ static void udf_bitmap_free_blocks(struct super_block *sb,
                                        ((char *)bh->b_data)[(bit + i) >> 3]);
                        } else {
                                if (inode)
-                                       DQUOT_FREE_BLOCK(inode, 1);
+                                       vfs_dq_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 (DQUOT_PREALLOC_BLOCK(inode, 1))
+                       else if (vfs_dq_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);
-                               DQUOT_FREE_BLOCK(inode, 1);
+                               vfs_dq_free_block(inode, 1);
                                goto out;
                        }
                        block_count--;
@@ -393,7 +393,7 @@ got_block:
        /*
         * Check quota for allocation of this block.
         */
-       if (inode && DQUOT_ALLOC_BLOCK(inode, 1)) {
+       if (inode && vfs_dq_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)
-               DQUOT_FREE_BLOCK(inode, count);
+               vfs_dq_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 && DQUOT_PREALLOC_BLOCK(inode,
+               if (inode && vfs_dq_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 && DQUOT_ALLOC_BLOCK(inode, 1)) {
+       if (inode && vfs_dq_alloc_block(inode, 1)) {
                brelse(goal_epos.bh);
                mutex_unlock(&sbi->s_alloc_mutex);
                *err = -EDQUOT;
index 31fc84297ddb545809e2033a2b5d6c4bf427716a..47dbe5613f90ff456b2a52f4a8a4c8aee8f6fb12 100644 (file)
@@ -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.
         */
-       DQUOT_FREE_INODE(inode);
-       DQUOT_DROP(inode);
+       vfs_dq_free_inode(inode);
+       vfs_dq_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 (DQUOT_ALLOC_INODE(inode)) {
-               DQUOT_DROP(inode);
+       if (vfs_dq_alloc_inode(inode)) {
+               vfs_dq_drop(inode);
                inode->i_flags |= S_NOQUOTA;
                inode->i_nlink = 0;
                iput(inode);
index 0d9ada173739c2c0ef701ff361afda1843cfd543..54c16ec95dfff52ff9113f0b61ab50d602bd58f9 100644 (file)
@@ -85,7 +85,7 @@ void ufs_free_fragments(struct inode *inode, u64 fragment, unsigned count)
                                   "bit already cleared for fragment %u", i);
        }
        
-       DQUOT_FREE_BLOCK (inode, count);
+       vfs_dq_free_block(inode, count);
 
        
        fs32_add(sb, &ucg->cg_cs.cs_nffree, count);
@@ -195,7 +195,7 @@ do_more:
                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);
-               DQUOT_FREE_BLOCK(inode, uspi->s_fpb);
+               vfs_dq_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(DQUOT_ALLOC_BLOCK(inode, count)) {
+       if (vfs_dq_alloc_block(inode, count)) {
                *err = -EDQUOT;
                return 0;
        }
@@ -664,7 +664,7 @@ cg_found:
                for (i = count; i < uspi->s_fpb; i++)
                        ubh_setbit (UCPI_UBH(ucpi), ucpi->c_freeoff, goal + i);
                i = uspi->s_fpb - count;
-               DQUOT_FREE_BLOCK(inode, i);
+               vfs_dq_free_block(inode, i);
 
                fs32_add(sb, &ucg->cg_cs.cs_nffree, i);
                uspi->cs_total.cs_nffree += i;
@@ -676,7 +676,7 @@ cg_found:
        result = ufs_bitmap_search (sb, ucpi, goal, allocsize);
        if (result == INVBLOCK)
                return 0;
-       if(DQUOT_ALLOC_BLOCK(inode, count)) {
+       if (vfs_dq_alloc_block(inode, count)) {
                *err = -EDQUOT;
                return 0;
        }
@@ -747,7 +747,7 @@ gotit:
        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(DQUOT_ALLOC_BLOCK(inode, uspi->s_fpb)) {
+       if (vfs_dq_alloc_block(inode, uspi->s_fpb)) {
                *err = -EDQUOT;
                return INVBLOCK;
        }
index 6f5dcf0060960c9999397fe64820a8db86c31c6d..3527c00fef0d7ebfc8a3df39a96618073ff6d883 100644 (file)
@@ -95,8 +95,8 @@ void ufs_free_inode (struct inode * inode)
 
        is_directory = S_ISDIR(inode->i_mode);
 
-       DQUOT_FREE_INODE(inode);
-       DQUOT_DROP(inode);
+       vfs_dq_free_inode(inode);
+       vfs_dq_drop(inode);
 
        clear_inode (inode);
 
@@ -355,8 +355,8 @@ cg_found:
 
        unlock_super (sb);
 
-       if (DQUOT_ALLOC_INODE(inode)) {
-               DQUOT_DROP(inode);
+       if (vfs_dq_alloc_inode(inode)) {
+               vfs_dq_drop(inode);
                err = -EDQUOT;
                goto fail_without_unlock;
        }
index 39f8778985655b1f1a166575e013b940af7965d4..3d2512c21f05c7d6ade3f2b64f2231f9b924c94d 100644 (file)
@@ -622,7 +622,6 @@ 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.
@@ -655,11 +654,12 @@ static int ufs1_read_inode(struct inode *inode, struct ufs_inode *ufs_inode)
 
        
        if (S_ISCHR(mode) || S_ISBLK(mode) || inode->i_blocks) {
-               for (i = 0; i < (UFS_NDADDR + UFS_NINDIR); i++)
-                       ufsi->i_u1.i_data[i] = ufs_inode->ui_u2.ui_addr.ui_db[i];
+               memcpy(ufsi->i_u1.i_data, &ufs_inode->ui_u2.ui_addr,
+                      sizeof(ufs_inode->ui_u2.ui_addr));
        } else {
-               for (i = 0; i < (UFS_NDADDR + UFS_NINDIR) * 4; i++)
-                       ufsi->i_u1.i_symlink[i] = ufs_inode->ui_u2.ui_symlink[i];
+               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;
        }
        return 0;
 }
@@ -669,7 +669,6 @@ 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);
        /*
@@ -704,12 +703,12 @@ static int ufs2_read_inode(struct inode *inode, struct ufs2_inode *ufs2_inode)
        */
 
        if (S_ISCHR(mode) || S_ISBLK(mode) || inode->i_blocks) {
-               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];
+               memcpy(ufsi->i_u1.u2_i_data, &ufs2_inode->ui_u2.ui_addr,
+                      sizeof(ufs2_inode->ui_u2.ui_addr));
        } else {
-               for (i = 0; i < (UFS_NDADDR + UFS_NINDIR) * 4; i++)
-                       ufsi->i_u1.i_symlink[i] = ufs2_inode->ui_u2.ui_symlink[i];
+               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;
        }
        return 0;
 }
@@ -781,7 +780,6 @@ 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);
@@ -809,12 +807,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) {
-               for (i = 0; i < (UFS_NDADDR + UFS_NINDIR); i++)
-                       ufs_inode->ui_u2.ui_addr.ui_db[i] = ufsi->i_u1.i_data[i];
+               memcpy(&ufs_inode->ui_u2.ui_addr, ufsi->i_u1.i_data,
+                      sizeof(ufs_inode->ui_u2.ui_addr));
        }
        else {
-               for (i = 0; i < (UFS_NDADDR + UFS_NINDIR) * 4; i++)
-                       ufs_inode->ui_u2.ui_symlink[i] = ufsi->i_u1.i_symlink[i];
+               memcpy(&ufs_inode->ui_u2.ui_symlink, ufsi->i_u1.i_symlink,
+                      sizeof(ufs_inode->ui_u2.ui_symlink));
        }
 
        if (!inode->i_nlink)
@@ -825,7 +823,6 @@ 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);
@@ -850,11 +847,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) {
-               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];
+               memcpy(&ufs_inode->ui_u2.ui_addr, ufsi->i_u1.u2_i_data,
+                      sizeof(ufs_inode->ui_u2.ui_addr));
        } else {
-               for (i = 0; i < (UFS_NDADDR + UFS_NINDIR) * 4; i++)
-                       ufs_inode->ui_u2.ui_symlink[i] = ufsi->i_u1.i_symlink[i];
+               memcpy(&ufs_inode->ui_u2.ui_symlink, ufsi->i_u1.i_symlink,
+                      sizeof(ufs_inode->ui_u2.ui_symlink));
        }
 
        if (!inode->i_nlink)
index e3a9b1fac75a2c4f6d04c94f6c22bb39d530d523..23119fe7ad6241e504f4bc7063c22988882d8a0c 100644 (file)
@@ -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((char*)&UFS_I(inode)->i_u1.i_data,symname,l);
+               memcpy(UFS_I(inode)->i_u1.i_symlink, symname, l);
                inode->i_size = l-1;
        }
        mark_inode_dirty(inode);
index 261a1c2f22dd0bc0c0eac67937e13c85f695006b..e1c1fc5ee2395cca67ad36e10f0577fdef0f0651 100644 (file)
@@ -636,6 +636,7 @@ 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;
@@ -1069,6 +1070,16 @@ magic_found:
                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);
index 11c035168ea6e3c1201ee8f95ed1693c72e566e2..69b3427d7885e0a42e1caa65a22c1ab79d5b015d 100644 (file)
@@ -23,7 +23,7 @@ struct ufs_sb_info {
 struct ufs_inode_info {
        union {
                __fs32  i_data[15];
-               __u8    i_symlink[4*15];
+               __u8    i_symlink[2 * 4 * 15];
                __fs64  u2_i_data[15];
        } i_u1;
        __u32   i_flags;
index bd7ac793be19b80254c421922ede4d540436fd47..f19fd9045ea0a621e05bc6eb11d515a78656f8bb 100644 (file)
@@ -165,15 +165,8 @@ 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,
index 3fd2194ff57324670062c5cfc12f95d05fd75f22..b880864672de75e09cfd522f1f6df1fded3ba56b 100644 (file)
@@ -125,6 +125,13 @@ 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;
@@ -178,6 +185,7 @@ 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);
index c66d22487bf8c53e7dfb0ee6c34b8cbe726cae56..15156364d196a64103f27b5700756f51882a5eab 100644 (file)
@@ -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 */
-       struct dentry_operations *d_op;
+       const struct dentry_operations *d_op;
        struct super_block *d_sb;       /* The root of the dentry tree */
        void *d_fsdata;                 /* fs-specific data */
 
index 1cd44f727dac386c90b707f2fe4541b16fdb8d59..42436ae42f7022468fd3fc8f4a947b69f704a7ed 100644 (file)
@@ -1064,34 +1064,147 @@ 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 */
-#define fcntl_getlk(a, b) ({ -EINVAL; })
-#define fcntl_setlk(a, b, c, d) ({ -EACCES; })
+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;
+}
+
 #if BITS_PER_LONG == 32
-#define fcntl_getlk64(a, b) ({ -EINVAL; })
-#define fcntl_setlk64(a, b, c, d) ({ -EACCES; })
+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;
+}
 #endif
-#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; })
+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;
+}
+
 #endif /* !CONFIG_FILE_LOCKING */
 
 
@@ -1607,7 +1720,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 int simple_set_mnt(struct vfsmount *mnt, struct super_block *sb);
+extern void 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 */
@@ -1688,13 +1801,44 @@ static inline int break_lease(struct inode *inode, unsigned int mode)
        return 0;
 }
 #else /* !CONFIG_FILE_LOCKING */
-#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; })
+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;
+}
+
 #endif /* CONFIG_FILE_LOCKING */
 
 /* fs/open.c */
@@ -1731,6 +1875,13 @@ 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
@@ -1882,7 +2033,6 @@ 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);
index f69e66d151cca2b2972f720b0d477daebc0ad429..30b06c89394482f86955dfa69f8a9f912e98388d 100644 (file)
@@ -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 struct dentry_operations ncp_root_dentry_operations;
+extern const 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);
index db867b04ac3c21b66e39793149e121b4569ee41f..8cc8807f77d6da286c6225ccb4a8c69642b826e3 100644 (file)
@@ -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 struct dentry_operations nfs_dentry_operations;
+extern const 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);
index 2e5f00066afd2a5e625b6bfc34de395a65929cc8..43a713fce11cbfbd25571424e7201758f15b4bf5 100644 (file)
@@ -785,7 +785,7 @@ struct nfs_access_entry;
  */
 struct nfs_rpc_ops {
        u32     version;                /* Protocol version */
-       struct dentry_operations *dentry_ops;
+       const struct dentry_operations *dentry_ops;
        const struct inode_operations *dir_inode_ops;
        const struct inode_operations *file_inode_ops;
 
index d72d5d84fde54a02d54e8b7dbd580638ab1f67ff..78c48895b12a9bae5f64e2627b61f4bd92f4fce0 100644 (file)
@@ -198,6 +198,7 @@ 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 */
@@ -276,8 +277,6 @@ struct dquot {
        struct mem_dqblk dq_dqb;        /* Diskquota usage */
 };
 
-#define NODQUOT (struct dquot *)NULL
-
 #define QUOTA_OK          0
 #define NO_QUOTA          1
 
@@ -308,6 +307,14 @@ 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 */
index 0b35b3a1be05bc6a52aba62442ec638bbaf3a9dd..36353d95c8dbfb518687ad6c3b5d6e8db8fbe1f2 100644 (file)
@@ -35,6 +35,11 @@ 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);
 
@@ -183,6 +188,16 @@ 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)) {
@@ -193,6 +208,31 @@ 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))
@@ -339,6 +379,22 @@ 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);
@@ -354,67 +410,48 @@ 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_sb->s_blocksize_bits);
+       return vfs_dq_prealloc_space_nodirty(inode, nr << inode->i_blkbits);
 }
 
 static inline int vfs_dq_prealloc_block(struct inode *inode, qsize_t nr)
 {
-       return vfs_dq_prealloc_space(inode,
-                       nr << inode->i_sb->s_blocksize_bits);
+       return vfs_dq_prealloc_space(inode, nr << inode->i_blkbits);
 }
 
 static inline int vfs_dq_alloc_block_nodirty(struct inode *inode, qsize_t nr)
 {
-       return vfs_dq_alloc_space_nodirty(inode,
-                       nr << inode->i_sb->s_blocksize_bits);
+       return vfs_dq_alloc_space_nodirty(inode, nr << inode->i_blkbits);
 }
 
 static inline int vfs_dq_alloc_block(struct inode *inode, qsize_t nr)
 {
-       return vfs_dq_alloc_space(inode,
-                       nr << inode->i_sb->s_blocksize_bits);
+       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);
 }
 
 static inline void vfs_dq_free_block_nodirty(struct inode *inode, qsize_t nr)
 {
-       vfs_dq_free_space_nodirty(inode, nr << inode->i_sb->s_blocksize_bits);
+       vfs_dq_free_space_nodirty(inode, nr << inode->i_blkbits);
 }
 
 static inline void vfs_dq_free_block(struct inode *inode, qsize_t nr)
 {
-       vfs_dq_free_space(inode, nr << inode->i_sb->s_blocksize_bits);
+       vfs_dq_free_space(inode, nr << inode->i_blkbits);
 }
 
-/*
- * 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_ */
index 9edb5c4b79b4f1a88a0487f588c36fc6207f54a9..c500ca7239b21a465831e2b3f0454f14505ff3e9 100644 (file)
@@ -1071,7 +1071,8 @@ static int cgroup_get_sb(struct file_system_type *fs_type,
                mutex_unlock(&cgroup_mutex);
        }
 
-       return simple_set_mnt(mnt, sb);
+       simple_set_mnt(mnt, sb);
+       return 0;
 
  free_cg_links:
        free_cg_links(&tmp_cg_links);
@@ -1627,7 +1628,7 @@ static struct inode_operations cgroup_dir_inode_operations = {
 static int cgroup_create_file(struct dentry *dentry, int mode,
                                struct super_block *sb)
 {
-       static struct dentry_operations cgroup_dops = {
+       static const struct dentry_operations cgroup_dops = {
                .d_iput = cgroup_diput,
        };
 
index af0205ff56f2ad3e8ed7f4edfff722291d763f34..0b14b79c03aff9503f4c56f80b4a6e5850737ca8 100644 (file)
@@ -328,7 +328,7 @@ static char *sockfs_dname(struct dentry *dentry, char *buffer, int buflen)
                                dentry->d_inode->i_ino);
 }
 
-static struct dentry_operations sockfs_dentry_operations = {
+static const struct dentry_operations sockfs_dentry_operations = {
        .d_delete = sockfs_delete_dentry,
        .d_dname  = sockfs_dname,
 };
index 577385a4a5dc51219f1b2d6c8e6dec8568b3c2af..9ced0628d69c35d44aa158b6d615acf8086278c6 100644 (file)
@@ -480,7 +480,7 @@ static int rpc_delete_dentry(struct dentry *dentry)
        return 1;
 }
 
-static struct dentry_operations rpc_dentry_operations = {
+static const struct dentry_operations rpc_dentry_operations = {
        .d_delete = rpc_delete_dentry,
 };