summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/amigaffs.h1
-rw-r--r--include/linux/backing-dev.h30
-rw-r--r--include/linux/blk.h1
-rw-r--r--include/linux/blkdev.h9
-rw-r--r--include/linux/buffer_head.h29
-rw-r--r--include/linux/dqblk_v1.h18
-rw-r--r--include/linux/dqblk_v2.h20
-rw-r--r--include/linux/fs.h122
-rw-r--r--include/linux/hfs_sysdep.h2
-rw-r--r--include/linux/jbd.h1
-rw-r--r--include/linux/locks.h28
-rw-r--r--include/linux/mm.h1
-rw-r--r--include/linux/module.h2
-rw-r--r--include/linux/nbd.h1
-rw-r--r--include/linux/nfs_fs.h2
-rw-r--r--include/linux/page-flags.h9
-rw-r--r--include/linux/quota.h255
-rw-r--r--include/linux/quotacompat.h86
-rw-r--r--include/linux/quotaio_v1.h33
-rw-r--r--include/linux/quotaio_v2.h79
-rw-r--r--include/linux/quotaops.h96
-rw-r--r--include/linux/raid/md.h1
-rw-r--r--include/linux/reiserfs_fs.h8
-rw-r--r--include/linux/swap.h1
-rw-r--r--include/linux/ufs_fs.h1
-rw-r--r--include/linux/writeback.h27
-rw-r--r--include/linux/xqm.h159
27 files changed, 793 insertions, 229 deletions
diff --git a/include/linux/amigaffs.h b/include/linux/amigaffs.h
index 535c3bf41b9a..f02e8cbd0131 100644
--- a/include/linux/amigaffs.h
+++ b/include/linux/amigaffs.h
@@ -2,7 +2,6 @@
#define AMIGAFFS_H
#include <linux/types.h>
-#include <linux/locks.h>
#include <asm/byteorder.h>
diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h
new file mode 100644
index 000000000000..075cacc389e1
--- /dev/null
+++ b/include/linux/backing-dev.h
@@ -0,0 +1,30 @@
+/*
+ * include/linux/backing-dev.h
+ *
+ * low-level device information and state which is propagated up through
+ * to high-level code.
+ */
+
+#ifndef _LINUX_BACKING_DEV_H
+#define _LINUX_BACKING_DEV_H
+
+/*
+ * Bits in backing_dev_info.state
+ */
+enum bdi_state {
+ BDI_pdflush, /* A pdflush thread is working this device */
+ BDI_unused, /* Available bits start here */
+};
+
+struct backing_dev_info {
+ unsigned long ra_pages; /* max readahead in PAGE_CACHE_SIZE units */
+ unsigned long state; /* Always use atomic bitops on this */
+};
+
+extern struct backing_dev_info default_backing_dev_info;
+
+int writeback_acquire(struct backing_dev_info *bdi);
+int writeback_in_progress(struct backing_dev_info *bdi);
+void writeback_release(struct backing_dev_info *bdi);
+
+#endif /* _LINUX_BACKING_DEV_H */
diff --git a/include/linux/blk.h b/include/linux/blk.h
index 9be0913f6069..62d37b2b4c17 100644
--- a/include/linux/blk.h
+++ b/include/linux/blk.h
@@ -3,7 +3,6 @@
#include <linux/blkdev.h>
#include <linux/elevator.h>
-#include <linux/locks.h>
#include <linux/config.h>
#include <linux/spinlock.h>
#include <linux/compiler.h>
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index d8175ccc104c..ac373e6a2454 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -7,6 +7,7 @@
#include <linux/tqueue.h>
#include <linux/list.h>
#include <linux/pagemap.h>
+#include <linux/backing-dev.h>
#include <asm/scatterlist.h>
@@ -162,11 +163,7 @@ struct request_queue
make_request_fn *make_request_fn;
prep_rq_fn *prep_rq_fn;
- /*
- * The VM-level readahead tunable for this device. In
- * units of PAGE_CACHE_SIZE pages.
- */
- unsigned long ra_pages;
+ struct backing_dev_info backing_dev_info;
/*
* The queue owner gets to use this for whatever they like.
@@ -328,7 +325,7 @@ extern void blk_queue_hardsect_size(request_queue_t *q, unsigned short);
extern void blk_queue_segment_boundary(request_queue_t *q, unsigned long);
extern void blk_queue_assign_lock(request_queue_t *q, spinlock_t *);
extern void blk_queue_prep_rq(request_queue_t *q, prep_rq_fn *pfn);
-extern unsigned long *blk_get_ra_pages(struct block_device *bdev);
+extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev);
extern int blk_rq_map_sg(request_queue_t *, struct request *, struct scatterlist *);
extern void blk_dump_rq_flags(struct request *, char *);
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index 500a082b7bcc..5560b6ee5878 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -29,6 +29,7 @@ enum bh_state_bits {
struct page;
struct kiobuf;
struct buffer_head;
+struct address_space;
typedef void (bh_end_io_t)(struct buffer_head *bh, int uptodate);
/*
@@ -44,13 +45,13 @@ struct buffer_head {
struct page *b_page; /* the page this bh is mapped to */
sector_t b_blocknr; /* block number */
- unsigned short b_size; /* block size */
+ u32 b_size; /* block size */
char *b_data; /* pointer to data block */
struct block_device *b_bdev;
bh_end_io_t *b_end_io; /* I/O completion */
void *b_private; /* reserved for b_end_io */
- struct list_head b_inode_buffers; /* list of inode dirty buffers */
+ struct list_head b_assoc_buffers; /* associated with another mapping */
};
@@ -145,12 +146,19 @@ int try_to_free_buffers(struct page *);
void create_empty_buffers(struct page *, unsigned long,
unsigned long b_state);
void end_buffer_io_sync(struct buffer_head *bh, int uptodate);
+
+/* Things to do with buffers at mapping->private_list */
void buffer_insert_list(spinlock_t *lock,
struct buffer_head *, struct list_head *);
+void mark_buffer_dirty_inode(struct buffer_head *bh, struct inode *inode);
+int write_mapping_buffers(struct address_space *mapping);
+int inode_has_buffers(struct inode *);
+void invalidate_inode_buffers(struct inode *);
+int fsync_buffers_list(spinlock_t *lock, struct list_head *);
+int sync_mapping_buffers(struct address_space *mapping);
void mark_buffer_async_read(struct buffer_head *bh);
void mark_buffer_async_write(struct buffer_head *bh);
-void invalidate_inode_buffers(struct inode *);
void invalidate_bdev(struct block_device *, int);
void __invalidate_buffers(kdev_t dev, int);
int sync_blockdev(struct block_device *bdev);
@@ -161,8 +169,6 @@ int fsync_dev(kdev_t);
int fsync_bdev(struct block_device *);
int fsync_super(struct super_block *);
int fsync_no_super(struct block_device *);
-int fsync_buffers_list(spinlock_t *lock, struct list_head *);
-int inode_has_buffers(struct inode *);
struct buffer_head *__get_hash_table(struct block_device *, sector_t, int);
struct buffer_head * __getblk(struct block_device *, sector_t, int);
void __brelse(struct buffer_head *);
@@ -217,14 +223,6 @@ static inline void put_bh(struct buffer_head *bh)
atomic_dec(&bh->b_count);
}
-static inline void
-mark_buffer_dirty_inode(struct buffer_head *bh, struct inode *inode)
-{
- mark_buffer_dirty(bh);
- buffer_insert_list(&inode->i_bufferlist_lock,
- bh, &inode->i_dirty_buffers);
-}
-
/*
* If an error happens during the make_request, this function
* has to be recalled. It marks the buffer as clean and not
@@ -243,11 +241,6 @@ static inline void buffer_IO_error(struct buffer_head * bh)
bh->b_end_io(bh, buffer_uptodate(bh));
}
-static inline int fsync_inode_buffers(struct inode *inode)
-{
- return fsync_buffers_list(&inode->i_bufferlist_lock,
- &inode->i_dirty_buffers);
-}
static inline void brelse(struct buffer_head *buf)
{
diff --git a/include/linux/dqblk_v1.h b/include/linux/dqblk_v1.h
new file mode 100644
index 000000000000..42fbf4797156
--- /dev/null
+++ b/include/linux/dqblk_v1.h
@@ -0,0 +1,18 @@
+/*
+ * File with in-memory structures of old quota format
+ */
+
+#ifndef _LINUX_DQBLK_V1_H
+#define _LINUX_DQBLK_V1_H
+
+/* Id of quota format */
+#define QFMT_VFS_OLD 1
+
+/* Root squash turned on */
+#define V1_DQF_RSQUASH 1
+
+/* Special information about quotafile */
+struct v1_mem_dqinfo {
+};
+
+#endif /* _LINUX_DQBLK_V1_H */
diff --git a/include/linux/dqblk_v2.h b/include/linux/dqblk_v2.h
new file mode 100644
index 000000000000..4a6c5f6867bb
--- /dev/null
+++ b/include/linux/dqblk_v2.h
@@ -0,0 +1,20 @@
+/*
+ * Definitions of structures for vfsv0 quota format
+ */
+
+#ifndef _LINUX_DQBLK_V2_H
+#define _LINUX_DQBLK_V2_H
+
+#include <linux/types.h>
+
+/* id numbers of quota format */
+#define QFMT_VFS_V0 2
+
+/* Inmemory copy of version specific information */
+struct v2_mem_dqinfo {
+ unsigned int dqi_blocks;
+ unsigned int dqi_free_blk;
+ unsigned int dqi_free_entry;
+};
+
+#endif /* _LINUX_DQBLK_V2_H */
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 4b858f90c6fe..ab0a05dc8e26 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -112,7 +112,6 @@ extern int leases_enable, dir_notify_enable, lease_break_time;
#define MS_MOVE 8192
#define MS_REC 16384
#define MS_VERBOSE 32768
-#define MS_FLUSHING (1<<16) /* inodes are currently under writeout */
#define MS_ACTIVE (1<<30)
#define MS_NOUSER (1<<31)
@@ -156,7 +155,6 @@ extern int leases_enable, dir_notify_enable, lease_break_time;
#define IS_RDONLY(inode) ((inode)->i_sb->s_flags & MS_RDONLY)
#define IS_SYNC(inode) (__IS_FLG(inode, MS_SYNCHRONOUS) || ((inode)->i_flags & S_SYNC))
#define IS_MANDLOCK(inode) __IS_FLG(inode, MS_MANDLOCK)
-#define IS_FLUSHING(inode) __IS_FLG(inode, MS_FLUSHING)
#define IS_QUOTAINIT(inode) ((inode)->i_flags & S_QUOTA)
#define IS_NOQUOTA(inode) ((inode)->i_flags & S_NOQUOTA)
@@ -305,7 +303,9 @@ struct address_space_operations {
int (*direct_IO)(int, struct inode *, struct kiobuf *, unsigned long, int);
};
+struct backing_dev_info;
struct address_space {
+ struct inode *host; /* owner: inode, block_device */
struct radix_tree_root page_tree; /* radix tree of all pages */
rwlock_t page_lock; /* and rwlock protecting it */
struct list_head clean_pages; /* list of clean pages */
@@ -314,13 +314,15 @@ struct address_space {
struct list_head io_pages; /* being prepared for I/O */
unsigned long nrpages; /* number of total pages */
struct address_space_operations *a_ops; /* methods */
- struct inode *host; /* owner: inode, block_device */
list_t i_mmap; /* list of private mappings */
list_t i_mmap_shared; /* list of private mappings */
spinlock_t i_shared_lock; /* and spinlock protecting it */
unsigned long dirtied_when; /* jiffies of first page dirtying */
int gfp_mask; /* how to allocate the pages */
- unsigned long *ra_pages; /* device readahead */
+ struct backing_dev_info *backing_dev_info; /* device readahead, etc */
+ spinlock_t private_lock; /* for use by the address_space */
+ struct list_head private_list; /* ditto */
+ struct address_space *assoc_mapping; /* ditto */
};
struct char_device {
@@ -350,10 +352,6 @@ struct inode {
struct list_head i_hash;
struct list_head i_list;
struct list_head i_dentry;
-
- struct list_head i_dirty_buffers; /* uses i_bufferlist_lock */
- spinlock_t i_bufferlist_lock;
-
unsigned long i_ino;
atomic_t i_count;
kdev_t i_dev;
@@ -370,6 +368,7 @@ struct inode {
unsigned long i_blksize;
unsigned long i_blocks;
unsigned long i_version;
+ unsigned short i_bytes;
struct semaphore i_sem;
struct inode_operations *i_op;
struct file_operations *i_fop; /* former ->i_op->default_file_ops */
@@ -427,6 +426,39 @@ struct fown_struct {
int signum; /* posix.1b rt signal to be delivered on IO */
};
+static inline void inode_add_bytes(struct inode *inode, loff_t bytes)
+{
+ inode->i_blocks += bytes >> 9;
+ bytes &= 511;
+ inode->i_bytes += bytes;
+ if (inode->i_bytes >= 512) {
+ inode->i_blocks++;
+ inode->i_bytes -= 512;
+ }
+}
+
+static inline void inode_sub_bytes(struct inode *inode, loff_t bytes)
+{
+ inode->i_blocks -= bytes >> 9;
+ bytes &= 511;
+ if (inode->i_bytes < bytes) {
+ inode->i_blocks--;
+ inode->i_bytes += 512;
+ }
+ inode->i_bytes -= bytes;
+}
+
+static inline loff_t inode_get_bytes(struct inode *inode)
+{
+ return (((loff_t)inode->i_blocks) << 9) + inode->i_bytes;
+}
+
+static inline void inode_set_bytes(struct inode *inode, loff_t bytes)
+{
+ inode->i_blocks = bytes >> 9;
+ inode->i_bytes = bytes & 511;
+}
+
/*
* Track a single file's readahead state
*/
@@ -583,20 +615,6 @@ struct nameidata {
struct vfsmount *old_mnt;
};
-#define DQUOT_USR_ENABLED 0x01 /* User diskquotas enabled */
-#define DQUOT_GRP_ENABLED 0x02 /* Group diskquotas enabled */
-
-struct quota_mount_options
-{
- unsigned int flags; /* Flags for diskquotas on this device */
- struct semaphore dqio_sem; /* lock device while I/O in progress */
- struct semaphore dqoff_sem; /* serialize quota_off() and quota_on() on device */
- struct file *files[MAXQUOTAS]; /* fp's to quotafiles */
- time_t inode_expire[MAXQUOTAS]; /* expiretime for inode-quota */
- time_t block_expire[MAXQUOTAS]; /* expiretime for block-quota */
- char rsquash[MAXQUOTAS]; /* for quotas threat root as any other user */
-};
-
/*
* Umount options
*/
@@ -620,13 +638,13 @@ struct super_block {
kdev_t s_dev;
unsigned long s_blocksize;
unsigned long s_old_blocksize;
- unsigned short s_writeback_gen;/* To avoid writeback livelock */
unsigned char s_blocksize_bits;
unsigned char s_dirt;
unsigned long long s_maxbytes; /* Max file size */
struct file_system_type *s_type;
struct super_operations *s_op;
struct dquot_operations *dq_op;
+ struct quotactl_ops *s_qcop;
struct export_operations *s_export_op;
unsigned long s_flags;
unsigned long s_magic;
@@ -634,16 +652,18 @@ struct super_block {
struct rw_semaphore s_umount;
struct semaphore s_lock;
int s_count;
+ int s_syncing;
atomic_t s_active;
struct list_head s_dirty; /* dirty inodes */
+ struct list_head s_io; /* parked for writeback */
struct list_head s_locked_inodes;/* inodes being synced */
struct list_head s_anon; /* anonymous dentries for (nfs) exporting */
struct list_head s_files;
struct block_device *s_bdev;
struct list_head s_instances;
- struct quota_mount_options s_dquot; /* Diskquota specific options */
+ struct quota_info s_dquot; /* Diskquota specific options */
char s_id[32]; /* Informational name */
@@ -663,6 +683,19 @@ struct super_block {
};
/*
+ * Superblock locking.
+ */
+static inline void lock_super(struct super_block * sb)
+{
+ down(&sb->s_lock);
+}
+
+static inline void unlock_super(struct super_block * sb)
+{
+ up(&sb->s_lock);
+}
+
+/*
* VFS helper functions..
*/
extern int vfs_create(struct inode *, struct dentry *, int);
@@ -772,13 +805,6 @@ struct super_operations {
void (*read_inode) (struct inode *);
- /* reiserfs kludge. reiserfs needs 64 bits of information to
- ** find an inode. We are using the read_inode2 call to get
- ** that information. We don't like this, and are waiting on some
- ** VFS changes for the real solution.
- ** iget4 calls read_inode2, iff it is defined
- */
- void (*read_inode2) (struct inode *, void *) ;
void (*dirty_inode) (struct inode *);
void (*write_inode) (struct inode *, int);
void (*put_inode) (struct inode *);
@@ -802,6 +828,7 @@ struct super_operations {
#define I_LOCK 8
#define I_FREEING 16
#define I_CLEAR 32
+#define I_NEW 64
#define I_DIRTY (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES)
@@ -816,16 +843,6 @@ static inline void mark_inode_dirty_sync(struct inode *inode)
__mark_inode_dirty(inode, I_DIRTY_SYNC);
}
-struct dquot_operations {
- void (*initialize) (struct inode *, short);
- void (*drop) (struct inode *);
- int (*alloc_block) (struct inode *, unsigned long, char);
- int (*alloc_inode) (const struct inode *, unsigned long);
- void (*free_block) (struct inode *, unsigned long);
- void (*free_inode) (const struct inode *, unsigned long);
- int (*transfer) (struct inode *, struct iattr *);
-};
-
/**
* &export_operations - for nfsd to communicate with file systems
@@ -1118,7 +1135,6 @@ extern int invalidate_device(kdev_t, int);
extern void invalidate_inode_pages(struct inode *);
extern void invalidate_inode_pages2(struct address_space *);
extern void write_inode_now(struct inode *, int);
-extern void sync_inodes_sb(struct super_block *);
extern int filemap_fdatawrite(struct address_space *);
extern int filemap_fdatawait(struct address_space *);
extern void sync_supers(void);
@@ -1210,19 +1226,33 @@ extern void force_delete(struct inode *);
extern struct inode * igrab(struct inode *);
extern ino_t iunique(struct super_block *, ino_t);
-typedef int (*find_inode_t)(struct inode *, unsigned long, void *);
-extern struct inode * iget4(struct super_block *, unsigned long, find_inode_t, void *);
+extern struct inode * iget5_locked(struct super_block *, unsigned long, int (*test)(struct inode *, void *), int (*set)(struct inode *, void *), void *);
+extern struct inode * iget_locked(struct super_block *, unsigned long);
+extern void unlock_new_inode(struct inode *);
+
static inline struct inode *iget(struct super_block *sb, unsigned long ino)
{
- return iget4(sb, ino, NULL, NULL);
+ struct inode *inode = iget_locked(sb, ino);
+
+ if (inode && (inode->i_state & I_NEW)) {
+ sb->s_op->read_inode(inode);
+ unlock_new_inode(inode);
+ }
+
+ return inode;
}
extern void __iget(struct inode * inode);
extern void clear_inode(struct inode *);
extern struct inode *new_inode(struct super_block *);
extern void remove_suid(struct dentry *);
-extern void insert_inode_hash(struct inode *);
+
+extern void __insert_inode_hash(struct inode *, unsigned long hashval);
extern void remove_inode_hash(struct inode *);
+static inline void insert_inode_hash(struct inode *inode) {
+ __insert_inode_hash(inode, inode->i_ino);
+}
+
extern struct file * get_empty_filp(void);
extern void file_move(struct file *f, struct list_head *list);
extern void ll_rw_block(int, int, struct buffer_head * bh[]);
diff --git a/include/linux/hfs_sysdep.h b/include/linux/hfs_sysdep.h
index 62fcf2ea311f..a08d5aa9e39d 100644
--- a/include/linux/hfs_sysdep.h
+++ b/include/linux/hfs_sysdep.h
@@ -19,8 +19,8 @@
#include <linux/slab.h>
#include <linux/types.h>
-#include <linux/locks.h>
#include <linux/fs.h>
+#include <linux/sched.h>
#include <asm/byteorder.h>
#include <asm/unaligned.h>
diff --git a/include/linux/jbd.h b/include/linux/jbd.h
index 2752f3a7375d..4a96c4ac35b9 100644
--- a/include/linux/jbd.h
+++ b/include/linux/jbd.h
@@ -235,6 +235,7 @@ enum jbd_state_bits {
BUFFER_FNS(JBD, jbd)
BUFFER_FNS(JBDDirty, jbddirty)
+TAS_BUFFER_FNS(JBDDirty, jbddirty)
static inline struct buffer_head *jh2bh(struct journal_head *jh)
{
diff --git a/include/linux/locks.h b/include/linux/locks.h
deleted file mode 100644
index a380c5e4f0bb..000000000000
--- a/include/linux/locks.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifndef _LINUX_LOCKS_H
-#define _LINUX_LOCKS_H
-
-#ifndef _LINUX_MM_H
-#include <linux/mm.h>
-#endif
-#ifndef _LINUX_PAGEMAP_H
-#include <linux/pagemap.h>
-#endif
-
-/*
- * super-block locking. Again, interrupts may only unlock
- * a super-block (although even this isn't done right now.
- * nfs may need it).
- */
-
-static inline void lock_super(struct super_block * sb)
-{
- down(&sb->s_lock);
-}
-
-static inline void unlock_super(struct super_block * sb)
-{
- up(&sb->s_lock);
-}
-
-#endif /* _LINUX_LOCKS_H */
-
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 2f0b56f0183b..451cdff1ec16 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -454,7 +454,6 @@ void do_page_cache_readahead(struct file *file,
void page_cache_readahead(struct file *file, unsigned long offset);
void page_cache_readaround(struct file *file, unsigned long offset);
void handle_ra_thrashing(struct file *file);
-extern unsigned long default_ra_pages;
/* vma is the first one with address < vma->vm_end,
* and even address < vma->vm_start. Have to extend vma. */
diff --git a/include/linux/module.h b/include/linux/module.h
index f3a8370db10a..1021d58d1742 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -370,6 +370,8 @@ extern struct module *module_list;
#define EXPORT_SYMBOL_NOVERS(var) error this_object_must_be_defined_as_export_objs_in_the_Makefile
#define EXPORT_SYMBOL_GPL(var) error this_object_must_be_defined_as_export_objs_in_the_Makefile
+__asm__(".section __ksymtab,\"a\"\n.previous");
+
#else
#define __EXPORT_SYMBOL(sym, str) \
diff --git a/include/linux/nbd.h b/include/linux/nbd.h
index b6120317731d..556b847804ca 100644
--- a/include/linux/nbd.h
+++ b/include/linux/nbd.h
@@ -22,7 +22,6 @@
#ifdef MAJOR_NR
-#include <linux/locks.h>
#include <asm/semaphore.h>
#define LOCAL_END_REQUEST
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index 499b246788f4..a8a2259a8343 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -170,7 +170,6 @@ struct nfs_inode {
#define NFS_INO_REVALIDATING 0x0004 /* revalidating attrs */
#define NFS_IS_SNAPSHOT 0x0010 /* a snapshot file */
#define NFS_INO_FLUSH 0x0020 /* inode is due for flushing */
-#define NFS_INO_NEW 0x0040 /* hadn't been filled yet */
static inline struct nfs_inode *NFS_I(struct inode *inode)
{
@@ -208,7 +207,6 @@ do { \
#define NFS_FLAGS(inode) (NFS_I(inode)->flags)
#define NFS_REVALIDATING(inode) (NFS_FLAGS(inode) & NFS_INO_REVALIDATING)
#define NFS_STALE(inode) (NFS_FLAGS(inode) & NFS_INO_STALE)
-#define NFS_NEW(inode) (NFS_FLAGS(inode) & NFS_INO_NEW)
#define NFS_FILEID(inode) (NFS_I(inode)->fileid)
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index f56db65ebef3..52b7117c4f64 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -62,9 +62,8 @@
#define PG_arch_1 10
#define PG_reserved 11
-#define PG_launder 12 /* written out by VM pressure.. */
-#define PG_private 13 /* Has something at ->private */
-#define PG_writeback 14 /* Page is under writeback */
+#define PG_private 12 /* Has something at ->private */
+#define PG_writeback 13 /* Page is under writeback */
/*
* Global page accounting. One instance per CPU.
@@ -172,10 +171,6 @@ extern void get_page_state(struct page_state *ret);
#define SetPageReserved(page) set_bit(PG_reserved, &(page)->flags)
#define ClearPageReserved(page) clear_bit(PG_reserved, &(page)->flags)
-#define PageLaunder(page) test_bit(PG_launder, &(page)->flags)
-#define SetPageLaunder(page) set_bit(PG_launder, &(page)->flags)
-#define ClearPageLaunder(page) clear_bit(PG_launder, &(page)->flags)
-
#define SetPagePrivate(page) set_bit(PG_private, &(page)->flags)
#define ClearPagePrivate(page) clear_bit(PG_private, &(page)->flags)
#define PagePrivate(page) test_bit(PG_private, &(page)->flags)
diff --git a/include/linux/quota.h b/include/linux/quota.h
index b2d5de7368f6..0a36a5e59caf 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -40,30 +40,22 @@
#define _LINUX_QUOTA_
#include <linux/errno.h>
+#include <linux/types.h>
-/*
- * Convert diskblocks to blocks and the other way around.
- */
-#define dbtob(num) (num << BLOCK_SIZE_BITS)
-#define btodb(num) (num >> BLOCK_SIZE_BITS)
+#define __DQUOT_VERSION__ "dquot_6.5.1"
+#define __DQUOT_NUM_VERSION__ 6*10000+5*100+1
-/*
- * Convert count of filesystem blocks to diskquota blocks, meant
- * for filesystems where i_blksize != BLOCK_SIZE
- */
-#define fs_to_dq_blocks(num, blksize) (((num) * (blksize)) / BLOCK_SIZE)
+typedef __kernel_uid32_t qid_t; /* Type in which we store ids in memory */
+typedef __u64 qsize_t; /* Type in which we store sizes */
-/*
- * Definitions for disk quotas imposed on the average user
- * (big brother finally hits Linux).
- *
- * The following constants define the amount of time given a user
- * before the soft limits are treated as hard limits (usually resulting
- * in an allocation failure). The timer is started when the user crosses
- * their soft limit, it is reset when they go below their soft limit.
- */
-#define MAX_IQ_TIME 604800 /* (7*24*60*60) 1 week */
-#define MAX_DQ_TIME 604800 /* (7*24*60*60) 1 week */
+/* Size of blocks in which are counted size limits */
+#define QUOTABLOCK_BITS 10
+#define QUOTABLOCK_SIZE (1 << QUOTABLOCK_BITS)
+
+/* Conversion routines from and to quota blocks */
+#define qb2kb(x) ((x) << (QUOTABLOCK_BITS-10))
+#define kb2qb(x) ((x) >> (QUOTABLOCK_BITS-10))
+#define toqb(x) (((x) + QUOTABLOCK_SIZE - 1) >> QUOTABLOCK_BITS)
#define MAXQUOTAS 2
#define USRQUOTA 0 /* element used for user quotas */
@@ -78,9 +70,6 @@
"undefined", \
};
-#define QUOTAFILENAME "quota"
-#define QUOTAGROUP "staff"
-
/*
* Command definitions for the 'quotactl' system call.
* The commands are broken into a main command defined below
@@ -91,45 +80,111 @@
#define SUBCMDSHIFT 8
#define QCMD(cmd, type) (((cmd) << SUBCMDSHIFT) | ((type) & SUBCMDMASK))
-#define Q_QUOTAON 0x0100 /* enable quotas */
-#define Q_QUOTAOFF 0x0200 /* disable quotas */
-#define Q_GETQUOTA 0x0300 /* get limits and usage */
-#define Q_SETQUOTA 0x0400 /* set limits and usage */
-#define Q_SETUSE 0x0500 /* set usage */
-#define Q_SYNC 0x0600 /* sync disk copy of a filesystems quotas */
-#define Q_SETQLIM 0x0700 /* set limits */
-#define Q_GETSTATS 0x0800 /* get collected stats */
-#define Q_RSQUASH 0x1000 /* set root_squash option */
+#define Q_SYNC 0x800001 /* sync disk copy of a filesystems quotas */
+#define Q_QUOTAON 0x800002 /* turn quotas on */
+#define Q_QUOTAOFF 0x800003 /* turn quotas off */
+#define Q_GETFMT 0x800004 /* get quota format used on given filesystem */
+#define Q_GETINFO 0x800005 /* get information about quota files */
+#define Q_SETINFO 0x800006 /* set information about quota files */
+#define Q_GETQUOTA 0x800007 /* get user quota structure */
+#define Q_SETQUOTA 0x800008 /* set user quota structure */
+
+/*
+ * Quota structure used for communication with userspace via quotactl
+ * Following flags are used to specify which fields are valid
+ */
+#define QIF_BLIMITS 1
+#define QIF_SPACE 2
+#define QIF_ILIMITS 4
+#define QIF_INODES 8
+#define QIF_BTIME 16
+#define QIF_ITIME 32
+#define QIF_LIMITS (QIF_BLIMITS | QIF_ILIMITS)
+#define QIF_USAGE (QIF_SPACE | QIF_INODES)
+#define QIF_TIMES (QIF_BTIME | QIF_ITIME)
+#define QIF_ALL (QIF_LIMITS | QIF_USAGE | QIF_TIMES)
+
+struct if_dqblk {
+ __u64 dqb_bhardlimit;
+ __u64 dqb_bsoftlimit;
+ __u64 dqb_curspace;
+ __u64 dqb_ihardlimit;
+ __u64 dqb_isoftlimit;
+ __u64 dqb_curinodes;
+ __u64 dqb_btime;
+ __u64 dqb_itime;
+ __u32 dqb_valid;
+};
/*
- * The following structure defines the format of the disk quota file
- * (as it appears on disk) - the file is an array of these structures
- * indexed by user or group number.
+ * Structure used for setting quota information about file via quotactl
+ * Following flags are used to specify which fields are valid
*/
-struct dqblk {
+#define IIF_BGRACE 1
+#define IIF_IGRACE 2
+#define IIF_FLAGS 4
+#define IIF_ALL (IIF_BGRACE | IIF_IGRACE | IIF_FLAGS)
+
+struct if_dqinfo {
+ __u64 dqi_bgrace;
+ __u64 dqi_igrace;
+ __u32 dqi_flags;
+ __u32 dqi_valid;
+};
+
+#ifdef __KERNEL__
+
+#include <linux/xqm.h>
+#include <linux/dqblk_v1.h>
+#include <linux/dqblk_v2.h>
+
+/*
+ * Data for one user/group kept in memory
+ */
+struct mem_dqblk {
__u32 dqb_bhardlimit; /* absolute limit on disk blks alloc */
__u32 dqb_bsoftlimit; /* preferred limit on disk blks */
- __u32 dqb_curblocks; /* current block count */
+ qsize_t dqb_curspace; /* current used space */
__u32 dqb_ihardlimit; /* absolute limit on allocated inodes */
__u32 dqb_isoftlimit; /* preferred inode limit */
__u32 dqb_curinodes; /* current # allocated inodes */
- time_t dqb_btime; /* time limit for excessive disk use */
- time_t dqb_itime; /* time limit for excessive inode use */
+ time_t dqb_btime; /* time limit for excessive disk use */
+ time_t dqb_itime; /* time limit for excessive inode use */
};
/*
- * Shorthand notation.
+ * Data for one quotafile kept in memory
*/
-#define dq_bhardlimit dq_dqb.dqb_bhardlimit
-#define dq_bsoftlimit dq_dqb.dqb_bsoftlimit
-#define dq_curblocks dq_dqb.dqb_curblocks
-#define dq_ihardlimit dq_dqb.dqb_ihardlimit
-#define dq_isoftlimit dq_dqb.dqb_isoftlimit
-#define dq_curinodes dq_dqb.dqb_curinodes
-#define dq_btime dq_dqb.dqb_btime
-#define dq_itime dq_dqb.dqb_itime
+struct quota_format_type;
+
+struct mem_dqinfo {
+ struct quota_format_type *dqi_format;
+ int dqi_flags;
+ unsigned int dqi_bgrace;
+ unsigned int dqi_igrace;
+ union {
+ struct v1_mem_dqinfo v1_i;
+ struct v2_mem_dqinfo v2_i;
+ } u;
+};
+
+#define DQF_MASK 0xffff /* Mask for format specific flags */
+#define DQF_INFO_DIRTY 0x10000 /* Is info dirty? */
+#define DQF_ANY_DQUOT_DIRTY 0x20000 /* Is any dquot dirty? */
+
+extern inline void mark_info_dirty(struct mem_dqinfo *info)
+{
+ info->dqi_flags |= DQF_INFO_DIRTY;
+}
-#define dqoff(UID) ((loff_t)((UID) * sizeof (struct dqblk)))
+#define info_dirty(info) ((info)->dqi_flags & DQF_INFO_DIRTY)
+
+#define info_any_dirty(info) ((info)->dqi_flags & DQF_INFO_DIRTY ||\
+ (info)->dqi_flags & DQF_ANY_DQUOT_DIRTY)
+
+#define sb_dqopt(sb) (&(sb)->s_dquot)
+
+extern int nr_dquots, nr_free_dquots;
struct dqstats {
__u32 lookups;
@@ -142,9 +197,7 @@ struct dqstats {
__u32 syncs;
};
-#ifdef __KERNEL__
-
-extern int dquot_root_squash;
+extern struct dqstats dqstats;
#define NR_DQHASH 43 /* Just an arbitrary number */
@@ -161,36 +214,112 @@ struct dquot {
struct list_head dq_free; /* Free list element */
wait_queue_head_t dq_wait_lock; /* Pointer to waitqueue on dquot lock */
wait_queue_head_t dq_wait_free; /* Pointer to waitqueue for quota to be unused */
- int dq_count; /* Reference count */
+ int dq_count; /* Use count */
+ int dq_dup_ref; /* Number of duplicated refences */
/* fields after this point are cleared when invalidating */
struct super_block *dq_sb; /* superblock this applies to */
unsigned int dq_id; /* ID this applies to (uid, gid) */
+ loff_t dq_off; /* Offset of dquot on disk */
short dq_type; /* Type of quota */
short dq_flags; /* See DQ_* */
unsigned long dq_referenced; /* Number of times this dquot was
referenced during its lifetime */
- struct dqblk dq_dqb; /* Diskquota usage */
+ struct mem_dqblk dq_dqb; /* Diskquota usage */
};
#define NODQUOT (struct dquot *)NULL
-/*
- * Flags used for set_dqblk.
- */
-#define SET_QUOTA 0x02
-#define SET_USE 0x04
-#define SET_QLIMIT 0x08
-
#define QUOTA_OK 0
#define NO_QUOTA 1
+/* Operations which must be implemented by each quota format */
+struct quota_format_ops {
+ int (*check_quota_file)(struct super_block *sb, int type); /* Detect whether file is in our format */
+ int (*read_file_info)(struct super_block *sb, int type); /* Read main info about file - called on quotaon() */
+ int (*write_file_info)(struct super_block *sb, int type); /* Write main info about file */
+ int (*free_file_info)(struct super_block *sb, int type); /* Called on quotaoff() */
+ int (*read_dqblk)(struct dquot *dquot); /* Read structure for one user */
+ int (*commit_dqblk)(struct dquot *dquot); /* Write (or delete) structure for one user */
+};
+
+/* Operations working with dquots */
+struct dquot_operations {
+ void (*initialize) (struct inode *, int);
+ void (*drop) (struct inode *);
+ int (*alloc_space) (struct inode *, qsize_t, int);
+ int (*alloc_inode) (const struct inode *, unsigned long);
+ void (*free_space) (struct inode *, qsize_t);
+ void (*free_inode) (const struct inode *, unsigned long);
+ int (*transfer) (struct inode *, struct iattr *);
+};
+
+/* Operations handling requests from userspace */
+struct quotactl_ops {
+ int (*quota_on)(struct super_block *, int, int, char *);
+ int (*quota_off)(struct super_block *, int);
+ int (*quota_sync)(struct super_block *, int);
+ int (*get_info)(struct super_block *, int, struct if_dqinfo *);
+ int (*set_info)(struct super_block *, int, struct if_dqinfo *);
+ int (*get_dqblk)(struct super_block *, int, qid_t, struct if_dqblk *);
+ int (*set_dqblk)(struct super_block *, int, qid_t, struct if_dqblk *);
+ int (*get_xstate)(struct super_block *, struct fs_quota_stat *);
+ int (*set_xstate)(struct super_block *, unsigned int, int);
+ int (*get_xquota)(struct super_block *, int, qid_t, struct fs_disk_quota *);
+ int (*set_xquota)(struct super_block *, int, qid_t, struct fs_disk_quota *);
+};
+
+struct quota_format_type {
+ int qf_fmt_id; /* Quota format id */
+ struct quota_format_ops *qf_ops; /* Operations of format */
+ struct module *qf_owner; /* Module implementing quota format */
+ struct quota_format_type *qf_next;
+};
+
+#define DQUOT_USR_ENABLED 0x01 /* User diskquotas enabled */
+#define DQUOT_GRP_ENABLED 0x02 /* Group diskquotas enabled */
+
+struct quota_info {
+ unsigned int flags; /* Flags for diskquotas on this device */
+ struct semaphore dqio_sem; /* lock device while I/O in progress */
+ struct semaphore dqoff_sem; /* serialize quota_off() and quota_on() on device */
+ struct file *files[MAXQUOTAS]; /* fp's to quotafiles */
+ struct mem_dqinfo info[MAXQUOTAS]; /* Information for each quota type */
+ struct quota_format_ops *ops[MAXQUOTAS]; /* Operations for each type */
+};
+
+/* Inline would be better but we need to dereference super_block which is not defined yet */
+#define mark_dquot_dirty(dquot) do {\
+ dquot->dq_flags |= DQ_MOD;\
+ sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_flags |= DQF_ANY_DQUOT_DIRTY;\
+} while (0)
+
+#define dquot_dirty(dquot) ((dquot)->dq_flags & DQ_MOD)
+
+static inline int is_enabled(struct quota_info *dqopt, int type)
+{
+ switch (type) {
+ case USRQUOTA:
+ return dqopt->flags & DQUOT_USR_ENABLED;
+ case GRPQUOTA:
+ return dqopt->flags & DQUOT_GRP_ENABLED;
+ }
+ return 0;
+}
+
+#define sb_any_quota_enabled(sb) (is_enabled(sb_dqopt(sb), USRQUOTA) | is_enabled(sb_dqopt(sb), GRPQUOTA))
+
+#define sb_has_quota_enabled(sb, type) (is_enabled(sb_dqopt(sb), type))
+
+int register_quota_format(struct quota_format_type *fmt);
+void unregister_quota_format(struct quota_format_type *fmt);
+
#else
# /* nodep */ include <sys/cdefs.h>
__BEGIN_DECLS
-long quotactl __P ((int, const char *, int, caddr_t));
+long quotactl __P ((unsigned int, const char *, int, caddr_t));
__END_DECLS
#endif /* __KERNEL__ */
diff --git a/include/linux/quotacompat.h b/include/linux/quotacompat.h
new file mode 100644
index 000000000000..484aac17efc9
--- /dev/null
+++ b/include/linux/quotacompat.h
@@ -0,0 +1,86 @@
+/*
+ * Definition of symbols used for backward compatible interface
+ */
+
+#ifndef _LINUX_QUOTACOMPAT_
+#define _LINUX_QUOTACOMPAT_
+
+#include <linux/types.h>
+#include <linux/quota.h>
+
+struct v1c_mem_dqblk {
+ __u32 dqb_bhardlimit; /* absolute limit on disk blks alloc */
+ __u32 dqb_bsoftlimit; /* preferred limit on disk blks */
+ __u32 dqb_curblocks; /* current block count */
+ __u32 dqb_ihardlimit; /* maximum # allocated inodes */
+ __u32 dqb_isoftlimit; /* preferred inode limit */
+ __u32 dqb_curinodes; /* current # allocated inodes */
+ time_t dqb_btime; /* time limit for excessive disk use */
+ time_t dqb_itime; /* time limit for excessive files */
+};
+
+struct v1c_dqstats {
+ __u32 lookups;
+ __u32 drops;
+ __u32 reads;
+ __u32 writes;
+ __u32 cache_hits;
+ __u32 allocated_dquots;
+ __u32 free_dquots;
+ __u32 syncs;
+};
+
+struct v2c_mem_dqblk {
+ unsigned int dqb_ihardlimit;
+ unsigned int dqb_isoftlimit;
+ unsigned int dqb_curinodes;
+ unsigned int dqb_bhardlimit;
+ unsigned int dqb_bsoftlimit;
+ qsize_t dqb_curspace;
+ __kernel_time_t dqb_btime;
+ __kernel_time_t dqb_itime;
+};
+
+struct v2c_mem_dqinfo {
+ unsigned int dqi_bgrace;
+ unsigned int dqi_igrace;
+ unsigned int dqi_flags;
+ unsigned int dqi_blocks;
+ unsigned int dqi_free_blk;
+ unsigned int dqi_free_entry;
+};
+
+struct v2c_dqstats {
+ __u32 lookups;
+ __u32 drops;
+ __u32 reads;
+ __u32 writes;
+ __u32 cache_hits;
+ __u32 allocated_dquots;
+ __u32 free_dquots;
+ __u32 syncs;
+ __u32 version;
+};
+
+#define Q_COMP_QUOTAON 0x0100 /* enable quotas */
+#define Q_COMP_QUOTAOFF 0x0200 /* disable quotas */
+#define Q_COMP_SYNC 0x0600 /* sync disk copy of a filesystems quotas */
+
+#define Q_V1_GETQUOTA 0x0300 /* get limits and usage */
+#define Q_V1_SETQUOTA 0x0400 /* set limits and usage */
+#define Q_V1_SETUSE 0x0500 /* set usage */
+#define Q_V1_SETQLIM 0x0700 /* set limits */
+#define Q_V1_GETSTATS 0x0800 /* get collected stats */
+#define Q_V1_RSQUASH 0x1000 /* set root_squash option */
+
+#define Q_V2_SETQLIM 0x0700 /* set limits */
+#define Q_V2_GETINFO 0x0900 /* get info about quotas - graces, flags... */
+#define Q_V2_SETINFO 0x0A00 /* set info about quotas */
+#define Q_V2_SETGRACE 0x0B00 /* set inode and block grace */
+#define Q_V2_SETFLAGS 0x0C00 /* set flags for quota */
+#define Q_V2_GETQUOTA 0x0D00 /* get limits and usage */
+#define Q_V2_SETQUOTA 0x0E00 /* set limits and usage */
+#define Q_V2_SETUSE 0x0F00 /* set usage */
+#define Q_V2_GETSTATS 0x1100 /* get collected stats */
+
+#endif
diff --git a/include/linux/quotaio_v1.h b/include/linux/quotaio_v1.h
new file mode 100644
index 000000000000..746654b5de70
--- /dev/null
+++ b/include/linux/quotaio_v1.h
@@ -0,0 +1,33 @@
+#ifndef _LINUX_QUOTAIO_V1_H
+#define _LINUX_QUOTAIO_V1_H
+
+#include <linux/types.h>
+
+/*
+ * The following constants define the amount of time given a user
+ * before the soft limits are treated as hard limits (usually resulting
+ * in an allocation failure). The timer is started when the user crosses
+ * their soft limit, it is reset when they go below their soft limit.
+ */
+#define MAX_IQ_TIME 604800 /* (7*24*60*60) 1 week */
+#define MAX_DQ_TIME 604800 /* (7*24*60*60) 1 week */
+
+/*
+ * The following structure defines the format of the disk quota file
+ * (as it appears on disk) - the file is an array of these structures
+ * indexed by user or group number.
+ */
+struct v1_disk_dqblk {
+ __u32 dqb_bhardlimit; /* absolute limit on disk blks alloc */
+ __u32 dqb_bsoftlimit; /* preferred limit on disk blks */
+ __u32 dqb_curblocks; /* current block count */
+ __u32 dqb_ihardlimit; /* absolute limit on allocated inodes */
+ __u32 dqb_isoftlimit; /* preferred inode limit */
+ __u32 dqb_curinodes; /* current # allocated inodes */
+ time_t dqb_btime; /* time limit for excessive disk use */
+ time_t dqb_itime; /* time limit for excessive inode use */
+};
+
+#define v1_dqoff(UID) ((loff_t)((UID) * sizeof (struct v1_disk_dqblk)))
+
+#endif /* _LINUX_QUOTAIO_V1_H */
diff --git a/include/linux/quotaio_v2.h b/include/linux/quotaio_v2.h
new file mode 100644
index 000000000000..da4e02730bc8
--- /dev/null
+++ b/include/linux/quotaio_v2.h
@@ -0,0 +1,79 @@
+/*
+ * Definitions of structures for vfsv0 quota format
+ */
+
+#ifndef _LINUX_QUOTAIO_V2_H
+#define _LINUX_QUOTAIO_V2_H
+
+#include <linux/types.h>
+#include <linux/quota.h>
+
+/*
+ * Definitions of magics and versions of current quota files
+ */
+#define V2_INITQMAGICS {\
+ 0xd9c01f11, /* USRQUOTA */\
+ 0xd9c01927 /* GRPQUOTA */\
+}
+
+#define V2_INITQVERSIONS {\
+ 0, /* USRQUOTA */\
+ 0 /* GRPQUOTA */\
+}
+
+/*
+ * The following structure defines the format of the disk quota file
+ * (as it appears on disk) - the file is a radix tree whose leaves point
+ * to blocks of these structures.
+ */
+struct v2_disk_dqblk {
+ __u32 dqb_id; /* id this quota applies to */
+ __u32 dqb_ihardlimit; /* absolute limit on allocated inodes */
+ __u32 dqb_isoftlimit; /* preferred inode limit */
+ __u32 dqb_curinodes; /* current # allocated inodes */
+ __u32 dqb_bhardlimit; /* absolute limit on disk space (in QUOTABLOCK_SIZE) */
+ __u32 dqb_bsoftlimit; /* preferred limit on disk space (in QUOTABLOCK_SIZE) */
+ __u64 dqb_curspace; /* current space occupied (in bytes) */
+ __u64 dqb_btime; /* time limit for excessive disk use */
+ __u64 dqb_itime; /* time limit for excessive inode use */
+};
+
+/*
+ * Here are header structures as written on disk and their in-memory copies
+ */
+/* First generic header */
+struct v2_disk_dqheader {
+ __u32 dqh_magic; /* Magic number identifying file */
+ __u32 dqh_version; /* File version */
+};
+
+/* Header with type and version specific information */
+struct v2_disk_dqinfo {
+ __u32 dqi_bgrace; /* Time before block soft limit becomes hard limit */
+ __u32 dqi_igrace; /* Time before inode soft limit becomes hard limit */
+ __u32 dqi_flags; /* Flags for quotafile (DQF_*) */
+ __u32 dqi_blocks; /* Number of blocks in file */
+ __u32 dqi_free_blk; /* Number of first free block in the list */
+ __u32 dqi_free_entry; /* Number of block with at least one free entry */
+};
+
+/*
+ * Structure of header of block with quota structures. It is padded to 16 bytes so
+ * there will be space for exactly 18 quota-entries in a block
+ */
+struct v2_disk_dqdbheader {
+ __u32 dqdh_next_free; /* Number of next block with free entry */
+ __u32 dqdh_prev_free; /* Number of previous block with free entry */
+ __u16 dqdh_entries; /* Number of valid entries in block */
+ __u16 dqdh_pad1;
+ __u32 dqdh_pad2;
+};
+
+#define V2_DQINFOOFF sizeof(struct v2_disk_dqheader) /* Offset of info header in file */
+#define V2_DQBLKSIZE_BITS 10
+#define V2_DQBLKSIZE (1 << V2_DQBLKSIZE_BITS) /* Size of block with quota structures */
+#define V2_DQTREEOFF 1 /* Offset of tree in file in blocks */
+#define V2_DQTREEDEPTH 4 /* Depth of quota tree */
+#define V2_DQSTRINBLK ((V2_DQBLKSIZE - sizeof(struct v2_disk_dqdbheader)) / sizeof(struct v2_disk_dqblk)) /* Number of entries in one blocks */
+
+#endif /* _LINUX_QUOTAIO_V2_H */
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
index 0a1df9e1fe56..31b24e37c159 100644
--- a/include/linux/quotaops.h
+++ b/include/linux/quotaops.h
@@ -20,15 +20,15 @@
/*
* declaration of quota_function calls in kernel.
*/
-extern void dquot_initialize(struct inode *inode, short type);
+extern void sync_dquots(struct super_block *sb, int type);
+
+extern void dquot_initialize(struct inode *inode, int type);
extern void dquot_drop(struct inode *inode);
-extern int quota_off(struct super_block *sb, short type);
-extern int sync_dquots(struct super_block *sb, short type);
-extern int dquot_alloc_block(struct inode *inode, unsigned long number, char prealloc);
+extern int dquot_alloc_space(struct inode *inode, qsize_t number, int prealloc);
extern int dquot_alloc_inode(const struct inode *inode, unsigned long number);
-extern void dquot_free_block(struct inode *inode, unsigned long number);
+extern void dquot_free_space(struct inode *inode, qsize_t number);
extern void dquot_free_inode(const struct inode *inode, unsigned long number);
extern int dquot_transfer(struct inode *inode, struct iattr *iattr);
@@ -36,7 +36,11 @@ extern int dquot_transfer(struct inode *inode, struct iattr *iattr);
/*
* Operations supported for diskquotas.
*/
-#define sb_any_quota_enabled(sb) ((sb)->s_dquot.flags & (DQUOT_USR_ENABLED | DQUOT_GRP_ENABLED))
+extern struct dquot_operations dquot_operations;
+extern struct quotactl_ops vfs_quotactl_ops;
+
+#define sb_dquot_ops (&dquot_operations)
+#define sb_quotactl_ops (&vfs_quotactl_ops)
static __inline__ void DQUOT_INIT(struct inode *inode)
{
@@ -59,50 +63,50 @@ static __inline__ void DQUOT_DROP(struct inode *inode)
unlock_kernel();
}
-static __inline__ int DQUOT_PREALLOC_BLOCK_NODIRTY(struct inode *inode, int nr)
+static __inline__ int DQUOT_PREALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
{
lock_kernel();
if (sb_any_quota_enabled(inode->i_sb)) {
- /* Number of used blocks is updated in alloc_block() */
- if (inode->i_sb->dq_op->alloc_block(inode, fs_to_dq_blocks(nr, inode->i_sb->s_blocksize), 1) == NO_QUOTA) {
+ /* Used space is updated in alloc_space() */
+ if (inode->i_sb->dq_op->alloc_space(inode, nr, 1) == NO_QUOTA) {
unlock_kernel();
return 1;
}
}
else
- inode->i_blocks += nr << (inode->i_sb->s_blocksize_bits - 9);
+ inode_add_bytes(inode, nr);
unlock_kernel();
return 0;
}
-static __inline__ int DQUOT_PREALLOC_BLOCK(struct inode *inode, int nr)
+static __inline__ int DQUOT_PREALLOC_SPACE(struct inode *inode, qsize_t nr)
{
int ret;
- if (!(ret = DQUOT_PREALLOC_BLOCK_NODIRTY(inode, nr)))
+ if (!(ret = DQUOT_PREALLOC_SPACE_NODIRTY(inode, nr)))
mark_inode_dirty(inode);
return ret;
}
-static __inline__ int DQUOT_ALLOC_BLOCK_NODIRTY(struct inode *inode, int nr)
+static __inline__ int DQUOT_ALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
{
lock_kernel();
if (sb_any_quota_enabled(inode->i_sb)) {
- /* Number of used blocks is updated in alloc_block() */
- if (inode->i_sb->dq_op->alloc_block(inode, fs_to_dq_blocks(nr, inode->i_sb->s_blocksize), 0) == NO_QUOTA) {
+ /* Used space is updated in alloc_space() */
+ if (inode->i_sb->dq_op->alloc_space(inode, nr, 0) == NO_QUOTA) {
unlock_kernel();
return 1;
}
}
else
- inode->i_blocks += nr << (inode->i_sb->s_blocksize_bits - 9);
+ inode_add_bytes(inode, nr);
unlock_kernel();
return 0;
}
-static __inline__ int DQUOT_ALLOC_BLOCK(struct inode *inode, int nr)
+static __inline__ int DQUOT_ALLOC_SPACE(struct inode *inode, qsize_t nr)
{
int ret;
- if (!(ret = DQUOT_ALLOC_BLOCK_NODIRTY(inode, nr)))
+ if (!(ret = DQUOT_ALLOC_SPACE_NODIRTY(inode, nr)))
mark_inode_dirty(inode);
return ret;
}
@@ -121,19 +125,19 @@ static __inline__ int DQUOT_ALLOC_INODE(struct inode *inode)
return 0;
}
-static __inline__ void DQUOT_FREE_BLOCK_NODIRTY(struct inode *inode, int nr)
+static __inline__ void DQUOT_FREE_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
{
lock_kernel();
if (sb_any_quota_enabled(inode->i_sb))
- inode->i_sb->dq_op->free_block(inode, fs_to_dq_blocks(nr, inode->i_sb->s_blocksize));
+ inode->i_sb->dq_op->free_space(inode, nr);
else
- inode->i_blocks -= nr << (inode->i_sb->s_blocksize_bits - 9);
+ inode_sub_bytes(inode, nr);
unlock_kernel();
}
-static __inline__ void DQUOT_FREE_BLOCK(struct inode *inode, int nr)
+static __inline__ void DQUOT_FREE_SPACE(struct inode *inode, qsize_t nr)
{
- DQUOT_FREE_BLOCK_NODIRTY(inode, nr);
+ DQUOT_FREE_SPACE_NODIRTY(inode, nr);
mark_inode_dirty(inode);
}
@@ -160,13 +164,25 @@ static __inline__ int DQUOT_TRANSFER(struct inode *inode, struct iattr *iattr)
}
#define DQUOT_SYNC(sb) sync_dquots(sb, -1)
-#define DQUOT_OFF(sb) quota_off(sb, -1)
+
+static __inline__ int DQUOT_OFF(struct super_block *sb)
+{
+ int ret = -ENOSYS;
+
+ lock_kernel();
+ if (sb->s_qcop && sb->s_qcop->quota_off)
+ ret = sb->s_qcop->quota_off(sb, -1);
+ unlock_kernel();
+ return ret;
+}
#else
/*
* NO-OP when quota not configured.
*/
+#define sb_dquot_ops (NULL)
+#define sb_quotactl_ops (NULL)
#define DQUOT_INIT(inode) do { } while(0)
#define DQUOT_DROP(inode) do { } while(0)
#define DQUOT_ALLOC_INODE(inode) (0)
@@ -174,48 +190,56 @@ static __inline__ int DQUOT_TRANSFER(struct inode *inode, struct iattr *iattr)
#define DQUOT_SYNC(sb) do { } while(0)
#define DQUOT_OFF(sb) do { } while(0)
#define DQUOT_TRANSFER(inode, iattr) (0)
-extern __inline__ int DQUOT_PREALLOC_BLOCK_NODIRTY(struct inode *inode, int nr)
+extern __inline__ int DQUOT_PREALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
{
lock_kernel();
- inode->i_blocks += nr << (inode->i_sb->s_blocksize_bits - 9);
+ inode_add_bytes(inode, nr);
unlock_kernel();
return 0;
}
-extern __inline__ int DQUOT_PREALLOC_BLOCK(struct inode *inode, int nr)
+extern __inline__ int DQUOT_PREALLOC_SPACE(struct inode *inode, qsize_t nr)
{
- DQUOT_PREALLOC_BLOCK_NODIRTY(inode, nr);
+ DQUOT_PREALLOC_SPACE_NODIRTY(inode, nr);
mark_inode_dirty(inode);
return 0;
}
-extern __inline__ int DQUOT_ALLOC_BLOCK_NODIRTY(struct inode *inode, int nr)
+extern __inline__ int DQUOT_ALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
{
lock_kernel();
- inode->i_blocks += nr << (inode->i_sb->s_blocksize_bits - 9);
+ inode_add_bytes(inode, nr);
unlock_kernel();
return 0;
}
-extern __inline__ int DQUOT_ALLOC_BLOCK(struct inode *inode, int nr)
+extern __inline__ int DQUOT_ALLOC_SPACE(struct inode *inode, qsize_t nr)
{
- DQUOT_ALLOC_BLOCK_NODIRTY(inode, nr);
+ DQUOT_ALLOC_SPACE_NODIRTY(inode, nr);
mark_inode_dirty(inode);
return 0;
}
-extern __inline__ void DQUOT_FREE_BLOCK_NODIRTY(struct inode *inode, int nr)
+extern __inline__ void DQUOT_FREE_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
{
lock_kernel();
- inode->i_blocks -= nr << (inode->i_sb->s_blocksize_bits - 9);
+ inode_sub_bytes(inode, nr);
unlock_kernel();
}
-extern __inline__ void DQUOT_FREE_BLOCK(struct inode *inode, int nr)
+extern __inline__ void DQUOT_FREE_SPACE(struct inode *inode, qsize_t nr)
{
- DQUOT_FREE_BLOCK_NODIRTY(inode, nr);
+ DQUOT_FREE_SPACE_NODIRTY(inode, nr);
mark_inode_dirty(inode);
}
#endif /* CONFIG_QUOTA */
+
+#define DQUOT_PREALLOC_BLOCK_NODIRTY(inode, nr) DQUOT_PREALLOC_SPACE_NODIRTY(inode, ((qsize_t)(nr)) << (inode)->i_sb->s_blocksize_bits)
+#define DQUOT_PREALLOC_BLOCK(inode, nr) DQUOT_PREALLOC_SPACE(inode, ((qsize_t)(nr)) << (inode)->i_sb->s_blocksize_bits)
+#define DQUOT_ALLOC_BLOCK_NODIRTY(inode, nr) DQUOT_ALLOC_SPACE_NODIRTY(inode, ((qsize_t)(nr)) << (inode)->i_sb->s_blocksize_bits)
+#define DQUOT_ALLOC_BLOCK(inode, nr) DQUOT_ALLOC_SPACE(inode, ((qsize_t)(nr)) << (inode)->i_sb->s_blocksize_bits)
+#define DQUOT_FREE_BLOCK_NODIRTY(inode, nr) DQUOT_FREE_SPACE_NODIRTY(inode, ((qsize_t)(nr)) << (inode)->i_sb->s_blocksize_bits)
+#define DQUOT_FREE_BLOCK(inode, nr) DQUOT_FREE_SPACE(inode, ((qsize_t)(nr)) << (inode)->i_sb->s_blocksize_bits)
+
#endif /* _LINUX_QUOTAOPS_ */
diff --git a/include/linux/raid/md.h b/include/linux/raid/md.h
index bf586df47298..cb6332482af2 100644
--- a/include/linux/raid/md.h
+++ b/include/linux/raid/md.h
@@ -31,7 +31,6 @@
#include <linux/delay.h>
#include <net/checksum.h>
#include <linux/random.h>
-#include <linux/locks.h>
#include <linux/kernel_stat.h>
#include <asm/io.h>
#include <linux/completion.h>
diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h
index e98ccaf9d217..173279f6ff0a 100644
--- a/include/linux/reiserfs_fs.h
+++ b/include/linux/reiserfs_fs.h
@@ -1564,8 +1564,9 @@ extern struct item_operations * item_ops [TYPE_ANY + 1];
#define B_I_POS_UNFM_POINTER(bh,ih,pos) le32_to_cpu(*(((unp_t *)B_I_PITEM(bh,ih)) + (pos)))
#define PUT_B_I_POS_UNFM_POINTER(bh,ih,pos, val) do {*(((unp_t *)B_I_PITEM(bh,ih)) + (pos)) = cpu_to_le32(val); } while (0)
-struct reiserfs_iget4_args {
+struct reiserfs_iget_args {
__u32 objectid ;
+ __u32 dirid ;
} ;
/***************************************************************************/
@@ -1818,8 +1819,9 @@ void padd_item (char * item, int total_length, int length);
/* inode.c */
-void reiserfs_read_inode (struct inode * inode) ;
-void reiserfs_read_inode2(struct inode * inode, void *p) ;
+void reiserfs_read_locked_inode(struct inode * inode, struct reiserfs_iget_args *args) ;
+int reiserfs_find_actor(struct inode * inode, void *p) ;
+int reiserfs_init_locked_inode(struct inode * inode, void *p) ;
void reiserfs_delete_inode (struct inode * inode);
void reiserfs_write_inode (struct inode * inode, int) ;
struct dentry *reiserfs_get_dentry(struct super_block *, void *) ;
diff --git a/include/linux/swap.h b/include/linux/swap.h
index 1674b5acd6f7..3a376842c21c 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -91,6 +91,7 @@ struct swap_info_struct {
int next; /* next entry on swap list */
};
+struct inode;
extern int nr_swap_pages;
/* Swap 50% full? Release swapcache more aggressively.. */
diff --git a/include/linux/ufs_fs.h b/include/linux/ufs_fs.h
index 609d0dab2c6f..faccf5ad22d5 100644
--- a/include/linux/ufs_fs.h
+++ b/include/linux/ufs_fs.h
@@ -31,6 +31,7 @@
#include <linux/kernel.h>
#include <linux/time.h>
#include <linux/stat.h>
+#include <linux/fs.h>
#define UFS_BBLOCK 0
#define UFS_BBSIZE 8192
diff --git a/include/linux/writeback.h b/include/linux/writeback.h
index 1978e06d1131..9dc03210ee62 100644
--- a/include/linux/writeback.h
+++ b/include/linux/writeback.h
@@ -13,20 +13,27 @@ extern struct list_head inode_in_use;
extern struct list_head inode_unused;
/*
+ * Yes, writeback.h requires sched.h
+ * No, sched.h is not included from here.
+ */
+static inline int current_is_pdflush(void)
+{
+ return current->flags & PF_FLUSHER;
+}
+
+/*
* fs/fs-writeback.c
*/
#define WB_SYNC_NONE 0 /* Don't wait on anything */
#define WB_SYNC_LAST 1 /* Wait on the last-written mapping */
#define WB_SYNC_ALL 2 /* Wait on every mapping */
+#define WB_SYNC_HOLD 3 /* Hold the inode on sb_dirty for sys_sync() */
-void try_to_writeback_unused_inodes(unsigned long pexclusive);
-void writeback_single_inode(struct inode *inode,
- int sync, int *nr_to_write);
void writeback_unlocked_inodes(int *nr_to_write, int sync_mode,
unsigned long *older_than_this);
-void writeback_inodes_sb(struct super_block *);
void __wait_on_inode(struct inode * inode);
-void sync_inodes(void);
+void sync_inodes_sb(struct super_block *, int wait);
+void sync_inodes(int wait);
static inline void wait_on_inode(struct inode *inode)
{
@@ -37,17 +44,9 @@ static inline void wait_on_inode(struct inode *inode)
/*
* mm/page-writeback.c
*/
-/*
- * How much data to write out at a time in various places. This isn't
- * really very important - it's just here to prevent any thread from
- * locking an inode for too long and blocking other threads which wish
- * to write the same file for allocation throttling purposes.
- */
-#define WRITEOUT_PAGES ((4096 * 1024) / PAGE_CACHE_SIZE)
-
void balance_dirty_pages(struct address_space *mapping);
void balance_dirty_pages_ratelimited(struct address_space *mapping);
-int pdflush_flush(unsigned long nr_pages);
int pdflush_operation(void (*fn)(unsigned long), unsigned long arg0);
+int writeback_mapping(struct address_space *mapping, int *nr_to_write);
#endif /* WRITEBACK_H */
diff --git a/include/linux/xqm.h b/include/linux/xqm.h
new file mode 100644
index 000000000000..d077bc18a424
--- /dev/null
+++ b/include/linux/xqm.h
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 1995-2001 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2.1 of the GNU Lesser General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307,
+ * USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ */
+#ifndef _LINUX_XQM_H
+#define _LINUX_XQM_H
+
+#include <linux/types.h>
+
+/*
+ * Disk quota - quotactl(2) commands for the XFS Quota Manager (XQM).
+ */
+
+#define XQM_CMD(x) (('X'<<8)+(x)) /* note: forms first QCMD argument */
+#define Q_XQUOTAON XQM_CMD(0x1) /* enable accounting/enforcement */
+#define Q_XQUOTAOFF XQM_CMD(0x2) /* disable accounting/enforcement */
+#define Q_XGETQUOTA XQM_CMD(0x3) /* get disk limits and usage */
+#define Q_XSETQLIM XQM_CMD(0x4) /* set disk limits */
+#define Q_XGETQSTAT XQM_CMD(0x5) /* get quota subsystem status */
+#define Q_XQUOTARM XQM_CMD(0x6) /* free disk space used by dquots */
+
+/*
+ * fs_disk_quota structure:
+ *
+ * This contains the current quota information regarding a user/proj/group.
+ * It is 64-bit aligned, and all the blk units are in BBs (Basic Blocks) of
+ * 512 bytes.
+ */
+#define FS_DQUOT_VERSION 1 /* fs_disk_quota.d_version */
+typedef struct fs_disk_quota {
+ __s8 d_version; /* version of this structure */
+ __s8 d_flags; /* XFS_{USER,PROJ,GROUP}_QUOTA */
+ __u16 d_fieldmask; /* field specifier */
+ __u32 d_id; /* user, project, or group ID */
+ __u64 d_blk_hardlimit;/* absolute limit on disk blks */
+ __u64 d_blk_softlimit;/* preferred limit on disk blks */
+ __u64 d_ino_hardlimit;/* maximum # allocated inodes */
+ __u64 d_ino_softlimit;/* preferred inode limit */
+ __u64 d_bcount; /* # disk blocks owned by the user */
+ __u64 d_icount; /* # inodes owned by the user */
+ __s32 d_itimer; /* zero if within inode limits */
+ /* if not, we refuse service */
+ __s32 d_btimer; /* similar to above; for disk blocks */
+ __u16 d_iwarns; /* # warnings issued wrt num inodes */
+ __u16 d_bwarns; /* # warnings issued wrt disk blocks */
+ __s32 d_padding2; /* padding2 - for future use */
+ __u64 d_rtb_hardlimit;/* absolute limit on realtime blks */
+ __u64 d_rtb_softlimit;/* preferred limit on RT disk blks */
+ __u64 d_rtbcount; /* # realtime blocks owned */
+ __s32 d_rtbtimer; /* similar to above; for RT disk blks */
+ __u16 d_rtbwarns; /* # warnings issued wrt RT disk blks */
+ __s16 d_padding3; /* padding3 - for future use */
+ char d_padding4[8]; /* yet more padding */
+} fs_disk_quota_t;
+
+/*
+ * These fields are sent to Q_XSETQLIM to specify fields that need to change.
+ */
+#define FS_DQ_ISOFT (1<<0)
+#define FS_DQ_IHARD (1<<1)
+#define FS_DQ_BSOFT (1<<2)
+#define FS_DQ_BHARD (1<<3)
+#define FS_DQ_RTBSOFT (1<<4)
+#define FS_DQ_RTBHARD (1<<5)
+#define FS_DQ_LIMIT_MASK (FS_DQ_ISOFT | FS_DQ_IHARD | FS_DQ_BSOFT | \
+ FS_DQ_BHARD | FS_DQ_RTBSOFT | FS_DQ_RTBHARD)
+/*
+ * These timers can only be set in super user's dquot. For others, timers are
+ * automatically started and stopped. Superusers timer values set the limits
+ * for the rest. In case these values are zero, the DQ_{F,B}TIMELIMIT values
+ * defined below are used.
+ * These values also apply only to the d_fieldmask field for Q_XSETQLIM.
+ */
+#define FS_DQ_BTIMER (1<<6)
+#define FS_DQ_ITIMER (1<<7)
+#define FS_DQ_RTBTIMER (1<<8)
+#define FS_DQ_TIMER_MASK (FS_DQ_BTIMER | FS_DQ_ITIMER | FS_DQ_RTBTIMER)
+
+/*
+ * The following constants define the default amount of time given a user
+ * before the soft limits are treated as hard limits (usually resulting
+ * in an allocation failure). These may be modified by the quotactl(2)
+ * system call with the Q_XSETQLIM command.
+ */
+#define DQ_FTIMELIMIT (7 * 24*60*60) /* 1 week */
+#define DQ_BTIMELIMIT (7 * 24*60*60) /* 1 week */
+
+/*
+ * Various flags related to quotactl(2). Only relevant to XFS filesystems.
+ */
+#define XFS_QUOTA_UDQ_ACCT (1<<0) /* user quota accounting */
+#define XFS_QUOTA_UDQ_ENFD (1<<1) /* user quota limits enforcement */
+#define XFS_QUOTA_GDQ_ACCT (1<<2) /* group quota accounting */
+#define XFS_QUOTA_GDQ_ENFD (1<<3) /* group quota limits enforcement */
+
+#define XFS_USER_QUOTA (1<<0) /* user quota type */
+#define XFS_PROJ_QUOTA (1<<1) /* (IRIX) project quota type */
+#define XFS_GROUP_QUOTA (1<<2) /* group quota type */
+
+/*
+ * fs_quota_stat is the struct returned in Q_XGETQSTAT for a given file system.
+ * Provides a centralized way to get meta infomation about the quota subsystem.
+ * eg. space taken up for user and group quotas, number of dquots currently
+ * incore.
+ */
+#define FS_QSTAT_VERSION 1 /* fs_quota_stat.qs_version */
+
+/*
+ * Some basic infomation about 'quota files'.
+ */
+typedef struct fs_qfilestat {
+ __u64 qfs_ino; /* inode number */
+ __u64 qfs_nblks; /* number of BBs 512-byte-blks */
+ __u32 qfs_nextents; /* number of extents */
+} fs_qfilestat_t;
+
+typedef struct fs_quota_stat {
+ __s8 qs_version; /* version number for future changes */
+ __u16 qs_flags; /* XFS_QUOTA_{U,P,G}DQ_{ACCT,ENFD} */
+ __s8 qs_pad; /* unused */
+ fs_qfilestat_t qs_uquota; /* user quota storage information */
+ fs_qfilestat_t qs_gquota; /* group quota storage information */
+ __u32 qs_incoredqs; /* number of dquots incore */
+ __s32 qs_btimelimit; /* limit for blks timer */
+ __s32 qs_itimelimit; /* limit for inodes timer */
+ __s32 qs_rtbtimelimit;/* limit for rt blks timer */
+ __u16 qs_bwarnlimit; /* limit for num warnings */
+ __u16 qs_iwarnlimit; /* limit for num warnings */
+} fs_quota_stat_t;
+
+#endif /* _LINUX_XQM_H */