Commit ce9fb139 authored by Jan Kara's avatar Jan Kara Committed by Linus Torvalds

[PATCH] [6/13] quota-6-bytes

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...
parent f0071c7b
...@@ -972,7 +972,7 @@ int dquot_alloc_space(struct inode *inode, qsize_t number, int warn) ...@@ -972,7 +972,7 @@ int dquot_alloc_space(struct inode *inode, qsize_t number, int warn)
continue; continue;
dquot_incr_space(dquot[cnt], number); dquot_incr_space(dquot[cnt], number);
} }
inode->i_blocks += number >> 9; inode_add_bytes(inode, number);
/* NOBLOCK End */ /* NOBLOCK End */
ret = QUOTA_OK; ret = QUOTA_OK;
warn_put_all: warn_put_all:
...@@ -1040,7 +1040,7 @@ void dquot_free_space(struct inode *inode, qsize_t number) ...@@ -1040,7 +1040,7 @@ void dquot_free_space(struct inode *inode, qsize_t number)
dquot_decr_space(dquot, number); dquot_decr_space(dquot, number);
dqputduplicate(dquot); dqputduplicate(dquot);
} }
inode->i_blocks -= number >> 9; inode_sub_bytes(inode, number);
unlock_kernel(); unlock_kernel();
/* NOBLOCK End */ /* NOBLOCK End */
} }
...@@ -1103,7 +1103,7 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr) ...@@ -1103,7 +1103,7 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr)
} }
} }
/* NOBLOCK START: From now on we shouldn't block */ /* 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 */ /* Build the transfer_from list and check the limits */
for (cnt = 0; cnt < MAXQUOTAS; cnt++) { for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
/* The second test can fail when quotaoff is in progress... */ /* The second test can fail when quotaoff is in progress... */
...@@ -1162,9 +1162,9 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr) ...@@ -1162,9 +1162,9 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr)
struct dquot_operations dquot_operations = { struct dquot_operations dquot_operations = {
initialize: dquot_initialize, /* mandatory */ initialize: dquot_initialize, /* mandatory */
drop: dquot_drop, /* mandatory */ drop: dquot_drop, /* mandatory */
alloc_block: dquot_alloc_space, alloc_space: dquot_alloc_space,
alloc_inode: dquot_alloc_inode, alloc_inode: dquot_alloc_inode,
free_block: dquot_free_space, free_space: dquot_free_space,
free_inode: dquot_free_inode, free_inode: dquot_free_inode,
transfer: dquot_transfer transfer: dquot_transfer
}; };
......
...@@ -95,6 +95,7 @@ static struct inode *alloc_inode(struct super_block *sb) ...@@ -95,6 +95,7 @@ static struct inode *alloc_inode(struct super_block *sb)
atomic_set(&inode->i_writecount, 0); atomic_set(&inode->i_writecount, 0);
inode->i_size = 0; inode->i_size = 0;
inode->i_blocks = 0; inode->i_blocks = 0;
inode->i_bytes = 0;
inode->i_generation = 0; inode->i_generation = 0;
memset(&inode->i_dquot, 0, sizeof(inode->i_dquot)); memset(&inode->i_dquot, 0, sizeof(inode->i_dquot));
inode->i_pipe = NULL; inode->i_pipe = NULL;
......
...@@ -370,6 +370,7 @@ struct inode { ...@@ -370,6 +370,7 @@ struct inode {
unsigned long i_blksize; unsigned long i_blksize;
unsigned long i_blocks; unsigned long i_blocks;
unsigned long i_version; unsigned long i_version;
unsigned short i_bytes;
struct semaphore i_sem; struct semaphore i_sem;
struct inode_operations *i_op; struct inode_operations *i_op;
struct file_operations *i_fop; /* former ->i_op->default_file_ops */ struct file_operations *i_fop; /* former ->i_op->default_file_ops */
...@@ -427,6 +428,39 @@ struct fown_struct { ...@@ -427,6 +428,39 @@ struct fown_struct {
int signum; /* posix.1b rt signal to be delivered on IO */ 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 * Track a single file's readahead state
*/ */
......
...@@ -70,7 +70,7 @@ static __inline__ int DQUOT_PREALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t ...@@ -70,7 +70,7 @@ static __inline__ int DQUOT_PREALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t
} }
} }
else else
inode->i_blocks += nr >> 9; inode_add_bytes(inode, nr);
unlock_kernel(); unlock_kernel();
return 0; return 0;
} }
...@@ -94,7 +94,7 @@ static __inline__ int DQUOT_ALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr) ...@@ -94,7 +94,7 @@ static __inline__ int DQUOT_ALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
} }
} }
else else
inode->i_blocks += nr >> 9; inode_add_bytes(inode, nr);
unlock_kernel(); unlock_kernel();
return 0; return 0;
} }
...@@ -127,7 +127,7 @@ static __inline__ void DQUOT_FREE_SPACE_NODIRTY(struct inode *inode, qsize_t nr) ...@@ -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)) if (sb_any_quota_enabled(inode->i_sb))
inode->i_sb->dq_op->free_space(inode, nr); inode->i_sb->dq_op->free_space(inode, nr);
else else
inode->i_blocks -= nr >> 9; inode_sub_bytes(inode, nr);
unlock_kernel(); unlock_kernel();
} }
...@@ -177,7 +177,7 @@ static __inline__ int DQUOT_TRANSFER(struct inode *inode, struct iattr *iattr) ...@@ -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) extern __inline__ int DQUOT_PREALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
{ {
lock_kernel(); lock_kernel();
inode->i_blocks += nr >> 9; inode_add_bytes(inode, nr);
unlock_kernel(); unlock_kernel();
return 0; return 0;
} }
...@@ -192,7 +192,7 @@ extern __inline__ int DQUOT_PREALLOC_SPACE(struct inode *inode, qsize_t nr) ...@@ -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) extern __inline__ int DQUOT_ALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
{ {
lock_kernel(); lock_kernel();
inode->i_blocks += nr >> 9; inode_add_bytes(inode, nr);
unlock_kernel(); unlock_kernel();
return 0; return 0;
} }
...@@ -207,7 +207,7 @@ extern __inline__ int DQUOT_ALLOC_SPACE(struct inode *inode, qsize_t nr) ...@@ -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) extern __inline__ void DQUOT_FREE_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
{ {
lock_kernel(); lock_kernel();
inode->i_blocks -= nr >> 9; inode_sub_bytes(inode, nr);
unlock_kernel(); unlock_kernel();
} }
...@@ -222,8 +222,8 @@ extern __inline__ void DQUOT_FREE_SPACE(struct inode *inode, qsize_t nr) ...@@ -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_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_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_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_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_ */ #endif /* _LINUX_QUOTAOPS_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment