fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / include / linux / quotaops.h
index 9db474d..90c23f6 100644 (file)
@@ -10,7 +10,6 @@
 #ifndef _LINUX_QUOTAOPS_
 #define _LINUX_QUOTAOPS_
 
-#include <linux/config.h>
 #include <linux/smp_lock.h>
 
 #include <linux/fs.h>
@@ -38,8 +37,12 @@ extern int dquot_release(struct dquot *dquot);
 extern int dquot_commit_info(struct super_block *sb, int type);
 extern int dquot_mark_dquot_dirty(struct dquot *dquot);
 
+int remove_inode_dquot_ref(struct inode *inode, int type,
+                          struct list_head *tofree_head);
+
 extern int vfs_quota_on(struct super_block *sb, int type, int format_id, char *path);
-extern int vfs_quota_on_mount(int type, int format_id, struct dentry *dentry);
+extern int vfs_quota_on_mount(struct super_block *sb, char *qf_name,
+               int format_id, int type);
 extern int vfs_quota_off(struct super_block *sb, int type);
 #define vfs_quota_off_mount(sb, type) vfs_quota_off(sb, type)
 extern int vfs_quota_sync(struct super_block *sb, int type);
@@ -69,9 +72,22 @@ static __inline__ void DQUOT_INIT(struct inode *inode)
 /* The same as with DQUOT_INIT */
 static __inline__ void DQUOT_DROP(struct inode *inode)
 {
-       if (IS_QUOTAINIT(inode)) {
-               BUG_ON(!inode->i_sb);
-               inode->i_sb->dq_op->drop(inode);        /* Ops must be set when there's any quota... */
+       /* Here we can get arbitrary inode from clear_inode() so we have
+        * to be careful. OTOH we don't need locking as quota operations
+        * are allowed to change only at mount time */
+       if (!IS_NOQUOTA(inode) && inode->i_sb && inode->i_sb->dq_op
+           && inode->i_sb->dq_op->drop) {
+               int cnt;
+               /* Test before calling to rule out calls from proc and such
+                 * where we are not allowed to block. Note that this is
+                * actually reliable test even without the lock - the caller
+                * 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)
+                               break;
+               if (cnt < MAXQUOTAS)
+                       inode->i_sb->dq_op->drop(inode);
        }
 }
 
@@ -164,7 +180,7 @@ static __inline__ int DQUOT_OFF(struct super_block *sb)
 {
        int ret = -ENOSYS;
 
-       if (sb->s_qcop && sb->s_qcop->quota_off)
+       if (sb_any_quota_enabled(sb) && sb->s_qcop && sb->s_qcop->quota_off)
                ret = sb->s_qcop->quota_off(sb, -1);
        return ret;
 }
@@ -176,7 +192,6 @@ static __inline__ int DQUOT_OFF(struct super_block *sb)
  */
 #define sb_dquot_ops                           (NULL)
 #define sb_quotactl_ops                                (NULL)
-#define sync_dquots_dev(dev,type)              (NULL)
 #define DQUOT_INIT(inode)                      do { } while(0)
 #define DQUOT_DROP(inode)                      do { } while(0)
 #define DQUOT_ALLOC_INODE(inode)               (0)
@@ -184,38 +199,38 @@ static __inline__ int DQUOT_OFF(struct super_block *sb)
 #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_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
+static inline int DQUOT_PREALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
 {
        inode_add_bytes(inode, nr);
        return 0;
 }
 
-extern __inline__ int DQUOT_PREALLOC_SPACE(struct inode *inode, qsize_t nr)
+static inline int DQUOT_PREALLOC_SPACE(struct inode *inode, qsize_t nr)
 {
        DQUOT_PREALLOC_SPACE_NODIRTY(inode, nr);
        mark_inode_dirty(inode);
        return 0;
 }
 
-extern __inline__ int DQUOT_ALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
+static inline int DQUOT_ALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
 {
        inode_add_bytes(inode, nr);
        return 0;
 }
 
-extern __inline__ int DQUOT_ALLOC_SPACE(struct inode *inode, qsize_t nr)
+static inline int DQUOT_ALLOC_SPACE(struct inode *inode, qsize_t nr)
 {
        DQUOT_ALLOC_SPACE_NODIRTY(inode, nr);
        mark_inode_dirty(inode);
        return 0;
 }
 
-extern __inline__ void DQUOT_FREE_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
+static inline void DQUOT_FREE_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
 {
        inode_sub_bytes(inode, nr);
 }
 
-extern __inline__ void DQUOT_FREE_SPACE(struct inode *inode, qsize_t nr)
+static inline void DQUOT_FREE_SPACE(struct inode *inode, qsize_t nr)
 {
        DQUOT_FREE_SPACE_NODIRTY(inode, nr);
        mark_inode_dirty(inode);