]> git.hungrycats.org Git - linux/commitdiff
[PATCH] [6/13] quota-6-bytes
authorJan Kara <jack@suse.cz>
Mon, 20 May 2002 02:34:14 +0000 (19:34 -0700)
committerLinus Torvalds <torvalds@penguin.transmeta.com>
Mon, 20 May 2002 02:34:14 +0000 (19:34 -0700)
This patch implements counting of used space in inodes in bytes.
New field i_bytes is added and used space modulo 512 is kept in
it (rest is still kept in i_blocks). Functions manipulating both
i_blocks and i_bytes are implemented (inode_add_bytes(), inode_sub_bytes()
and inode_set_bytes()). Filesystems allocating only in whole blocks
can safely ignore i_bytes field and continue using i_blocks...

fs/dquot.c
fs/inode.c
include/linux/fs.h
include/linux/quotaops.h

index d697e4b18e1671144b89ef836d89dda84b70f5ea..1503708a465744a7686f2ce391a6a1909056fbd8 100644 (file)
@@ -972,7 +972,7 @@ int dquot_alloc_space(struct inode *inode, qsize_t number, int warn)
                        continue;
                dquot_incr_space(dquot[cnt], number);
        }
-       inode->i_blocks += number >> 9;
+       inode_add_bytes(inode, number);
        /* NOBLOCK End */
        ret = QUOTA_OK;
 warn_put_all:
@@ -1040,7 +1040,7 @@ void dquot_free_space(struct inode *inode, qsize_t number)
                dquot_decr_space(dquot, number);
                dqputduplicate(dquot);
        }
-       inode->i_blocks -= number >> 9;
+       inode_sub_bytes(inode, number);
        unlock_kernel();
        /* NOBLOCK End */
 }
@@ -1103,7 +1103,7 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr)
                }
        }
        /* NOBLOCK START: From now on we shouldn't block */
-       space = ((qsize_t)inode->i_blocks) << 9;
+       space = inode_get_bytes(inode);
        /* Build the transfer_from list and check the limits */
        for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
                /* The second test can fail when quotaoff is in progress... */
@@ -1162,9 +1162,9 @@ warn_put_all:
 struct dquot_operations dquot_operations = {
        initialize:     dquot_initialize,               /* mandatory */
        drop:           dquot_drop,                     /* mandatory */
-       alloc_block:    dquot_alloc_space,
+       alloc_space:    dquot_alloc_space,
        alloc_inode:    dquot_alloc_inode,
-       free_block:     dquot_free_space,
+       free_space:     dquot_free_space,
        free_inode:     dquot_free_inode,
        transfer:       dquot_transfer
 };
index 61e3f66787371b85fd37b6305db971b71678f927..0ceabe7b934b07cbf97dc16824c4c1c19ed25169 100644 (file)
@@ -95,6 +95,7 @@ static struct inode *alloc_inode(struct super_block *sb)
                atomic_set(&inode->i_writecount, 0);
                inode->i_size = 0;
                inode->i_blocks = 0;
+               inode->i_bytes = 0;
                inode->i_generation = 0;
                memset(&inode->i_dquot, 0, sizeof(inode->i_dquot));
                inode->i_pipe = NULL;
index 0f789728ce3abaf6d8376dad1cc502aaa3556190..f50388ea30dc7fb5c3a5e76e13910ad13a0c79da 100644 (file)
@@ -370,6 +370,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 +428,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
  */
index ab702b2607cfd88aed203da71c723086440525c8..b5da5ff5bb9abdc649d2bfd07d8b0410c2084fcb 100644 (file)
@@ -70,7 +70,7 @@ static __inline__ int DQUOT_PREALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t
                }
        }
        else
-               inode->i_blocks += nr >> 9;
+               inode_add_bytes(inode, nr);
        unlock_kernel();
        return 0;
 }
@@ -94,7 +94,7 @@ static __inline__ int DQUOT_ALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
                }
        }
        else
-               inode->i_blocks += nr >> 9;
+               inode_add_bytes(inode, nr);
        unlock_kernel();
        return 0;
 }
@@ -127,7 +127,7 @@ static __inline__ void DQUOT_FREE_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
        if (sb_any_quota_enabled(inode->i_sb))
                inode->i_sb->dq_op->free_space(inode, nr);
        else
-               inode->i_blocks -= nr >> 9;
+               inode_sub_bytes(inode, nr);
        unlock_kernel();
 }
 
@@ -177,7 +177,7 @@ static __inline__ int DQUOT_TRANSFER(struct inode *inode, struct iattr *iattr)
 extern __inline__ int DQUOT_PREALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
 {
        lock_kernel();
-       inode->i_blocks += nr >> 9;
+       inode_add_bytes(inode, nr);
        unlock_kernel();
        return 0;
 }
@@ -192,7 +192,7 @@ extern __inline__ int DQUOT_PREALLOC_SPACE(struct inode *inode, qsize_t nr)
 extern __inline__ int DQUOT_ALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
 {
        lock_kernel();
-       inode->i_blocks += nr >> 9;
+       inode_add_bytes(inode, nr);
        unlock_kernel();
        return 0;
 }
@@ -207,7 +207,7 @@ extern __inline__ int DQUOT_ALLOC_SPACE(struct inode *inode, qsize_t nr)
 extern __inline__ void DQUOT_FREE_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
 {
        lock_kernel();
-       inode->i_blocks -= nr >> 9;
+       inode_sub_bytes(inode, nr);
        unlock_kernel();
 }
 
@@ -222,8 +222,8 @@ extern __inline__ void DQUOT_FREE_SPACE(struct inode *inode, qsize_t nr)
 #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, fs_to_dq_blocks(nr, ((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, fs_to_dq_blocks(nr, ((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_ */