[GFS2] Fix unlinked file handling
This patch fixes the way we have been dealing with unlinked, but still open files. It removes all limits (other than memory for inodes, as per every other filesystem) on numbers of these which we can support on GFS2. It also means that (like other fs) its the responsibility of the last process to close the file to deallocate the storage, rather than the person who did the unlinking. Note that with GFS2, those two events might take place on different nodes. Also there are a number of other changes: o We use the Linux inode subsystem as it was intended to be used, wrt allocating GFS2 inodes o The Linux inode cache is now the point which we use for local enforcement of only holding one copy of the inode in core at once (previous to this we used the glock layer). o We no longer use the unlinked "special" file. We just ignore it completely. This makes unlinking more efficient. o We now use the 4th block allocation state. The previously unused state is used to track unlinked but still open inodes. o gfs2_inoded is no longer needed o Several fields are now no longer needed (and removed) from the in core struct gfs2_inode o Several fields are no longer needed (and removed) from the in core superblock There are a number of future possible optimisations and clean ups which have been made possible by this patch. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
This commit is contained in:
parent
22da645fd6
commit
feaa7bba02
|
@ -3,7 +3,7 @@ gfs2-y := acl.o bmap.o daemon.o dir.o eaops.o eattr.o glock.o \
|
||||||
glops.o inode.o lm.o log.o lops.o locking.o lvb.o main.o meta_io.o \
|
glops.o inode.o lm.o log.o lops.o locking.o lvb.o main.o meta_io.o \
|
||||||
mount.o ondisk.o ops_address.o ops_dentry.o ops_export.o ops_file.o \
|
mount.o ondisk.o ops_address.o ops_dentry.o ops_export.o ops_file.o \
|
||||||
ops_fstype.o ops_inode.o ops_super.o ops_vm.o page.o quota.o \
|
ops_fstype.o ops_inode.o ops_super.o ops_vm.o page.o quota.o \
|
||||||
recovery.o rgrp.o super.o sys.o trans.o unlinked.o util.o
|
recovery.o rgrp.o super.o sys.o trans.o util.o
|
||||||
|
|
||||||
obj-$(CONFIG_GFS2_FS_LOCKING_NOLOCK) += locking/nolock/
|
obj-$(CONFIG_GFS2_FS_LOCKING_NOLOCK) += locking/nolock/
|
||||||
obj-$(CONFIG_GFS2_FS_LOCKING_DLM) += locking/dlm/
|
obj-$(CONFIG_GFS2_FS_LOCKING_DLM) += locking/dlm/
|
||||||
|
|
|
@ -73,7 +73,7 @@ int gfs2_acl_validate_set(struct gfs2_inode *ip, int access,
|
||||||
|
|
||||||
int gfs2_acl_validate_remove(struct gfs2_inode *ip, int access)
|
int gfs2_acl_validate_remove(struct gfs2_inode *ip, int access)
|
||||||
{
|
{
|
||||||
if (!ip->i_sbd->sd_args.ar_posix_acl)
|
if (!GFS2_SB(&ip->i_inode)->sd_args.ar_posix_acl)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
if (current->fsuid != ip->i_di.di_uid && !capable(CAP_FOWNER))
|
if (current->fsuid != ip->i_di.di_uid && !capable(CAP_FOWNER))
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
@ -160,7 +160,7 @@ int gfs2_check_acl_locked(struct inode *inode, int mask)
|
||||||
struct posix_acl *acl = NULL;
|
struct posix_acl *acl = NULL;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
error = acl_get(inode->u.generic_ip, ACL_ACCESS, &acl, NULL, NULL, NULL);
|
error = acl_get(GFS2_I(inode), ACL_ACCESS, &acl, NULL, NULL, NULL);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
|
@ -175,7 +175,7 @@ int gfs2_check_acl_locked(struct inode *inode, int mask)
|
||||||
|
|
||||||
int gfs2_check_acl(struct inode *inode, int mask)
|
int gfs2_check_acl(struct inode *inode, int mask)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(inode);
|
||||||
struct gfs2_holder i_gh;
|
struct gfs2_holder i_gh;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
@ -192,7 +192,7 @@ int gfs2_check_acl(struct inode *inode, int mask)
|
||||||
|
|
||||||
static int munge_mode(struct gfs2_inode *ip, mode_t mode)
|
static int munge_mode(struct gfs2_inode *ip, mode_t mode)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
||||||
struct buffer_head *dibh;
|
struct buffer_head *dibh;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
@ -217,7 +217,7 @@ static int munge_mode(struct gfs2_inode *ip, mode_t mode)
|
||||||
|
|
||||||
int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip)
|
int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = dip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
|
||||||
struct posix_acl *acl = NULL, *clone;
|
struct posix_acl *acl = NULL, *clone;
|
||||||
struct gfs2_ea_request er;
|
struct gfs2_ea_request er;
|
||||||
mode_t mode = ip->i_di.di_mode;
|
mode_t mode = ip->i_di.di_mode;
|
||||||
|
|
|
@ -136,7 +136,7 @@ int gfs2_unstuff_dinode(struct gfs2_inode *ip, gfs2_unstuffer_t unstuffer,
|
||||||
|
|
||||||
static unsigned int calc_tree_height(struct gfs2_inode *ip, uint64_t size)
|
static unsigned int calc_tree_height(struct gfs2_inode *ip, uint64_t size)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
||||||
uint64_t *arr;
|
uint64_t *arr;
|
||||||
unsigned int max, height;
|
unsigned int max, height;
|
||||||
|
|
||||||
|
@ -169,7 +169,7 @@ static unsigned int calc_tree_height(struct gfs2_inode *ip, uint64_t size)
|
||||||
|
|
||||||
static int build_height(struct inode *inode, unsigned height)
|
static int build_height(struct inode *inode, unsigned height)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(inode);
|
||||||
unsigned new_height = height - ip->i_di.di_height;
|
unsigned new_height = height - ip->i_di.di_height;
|
||||||
struct buffer_head *dibh;
|
struct buffer_head *dibh;
|
||||||
struct buffer_head *blocks[GFS2_MAX_META_HEIGHT];
|
struct buffer_head *blocks[GFS2_MAX_META_HEIGHT];
|
||||||
|
@ -283,7 +283,7 @@ static int build_height(struct inode *inode, unsigned height)
|
||||||
static void find_metapath(struct gfs2_inode *ip, uint64_t block,
|
static void find_metapath(struct gfs2_inode *ip, uint64_t block,
|
||||||
struct metapath *mp)
|
struct metapath *mp)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
||||||
uint64_t b = block;
|
uint64_t b = block;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
|
@ -382,8 +382,8 @@ static struct buffer_head *gfs2_block_pointers(struct inode *inode, u64 lblock,
|
||||||
int *boundary,
|
int *boundary,
|
||||||
struct metapath *mp)
|
struct metapath *mp)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(inode);
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(inode);
|
||||||
struct buffer_head *bh;
|
struct buffer_head *bh;
|
||||||
int create = *new;
|
int create = *new;
|
||||||
unsigned int bsize;
|
unsigned int bsize;
|
||||||
|
@ -446,7 +446,7 @@ out:
|
||||||
|
|
||||||
static inline void bmap_lock(struct inode *inode, int create)
|
static inline void bmap_lock(struct inode *inode, int create)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(inode);
|
||||||
if (create)
|
if (create)
|
||||||
down_write(&ip->i_rw_mutex);
|
down_write(&ip->i_rw_mutex);
|
||||||
else
|
else
|
||||||
|
@ -455,7 +455,7 @@ static inline void bmap_lock(struct inode *inode, int create)
|
||||||
|
|
||||||
static inline void bmap_unlock(struct inode *inode, int create)
|
static inline void bmap_unlock(struct inode *inode, int create)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(inode);
|
||||||
if (create)
|
if (create)
|
||||||
up_write(&ip->i_rw_mutex);
|
up_write(&ip->i_rw_mutex);
|
||||||
else
|
else
|
||||||
|
@ -481,8 +481,8 @@ int gfs2_block_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, int *
|
||||||
|
|
||||||
int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsigned *extlen)
|
int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsigned *extlen)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(inode);
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(inode);
|
||||||
struct metapath mp;
|
struct metapath mp;
|
||||||
struct buffer_head *bh;
|
struct buffer_head *bh;
|
||||||
int boundary;
|
int boundary;
|
||||||
|
@ -541,7 +541,7 @@ static int recursive_scan(struct gfs2_inode *ip, struct buffer_head *dibh,
|
||||||
uint64_t block, int first, block_call_t bc,
|
uint64_t block, int first, block_call_t bc,
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
||||||
struct buffer_head *bh = NULL;
|
struct buffer_head *bh = NULL;
|
||||||
uint64_t *top, *bottom;
|
uint64_t *top, *bottom;
|
||||||
uint64_t bn;
|
uint64_t bn;
|
||||||
|
@ -609,8 +609,8 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh,
|
||||||
struct buffer_head *bh, uint64_t *top, uint64_t *bottom,
|
struct buffer_head *bh, uint64_t *top, uint64_t *bottom,
|
||||||
unsigned int height, void *data)
|
unsigned int height, void *data)
|
||||||
{
|
{
|
||||||
struct strip_mine *sm = (struct strip_mine *)data;
|
struct strip_mine *sm = data;
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
||||||
struct gfs2_rgrp_list rlist;
|
struct gfs2_rgrp_list rlist;
|
||||||
uint64_t bn, bstart;
|
uint64_t bn, bstart;
|
||||||
uint32_t blen;
|
uint32_t blen;
|
||||||
|
@ -756,7 +756,7 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh,
|
||||||
|
|
||||||
static int do_grow(struct gfs2_inode *ip, uint64_t size)
|
static int do_grow(struct gfs2_inode *ip, uint64_t size)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
||||||
struct gfs2_alloc *al;
|
struct gfs2_alloc *al;
|
||||||
struct buffer_head *dibh;
|
struct buffer_head *dibh;
|
||||||
unsigned int h;
|
unsigned int h;
|
||||||
|
@ -795,7 +795,7 @@ static int do_grow(struct gfs2_inode *ip, uint64_t size)
|
||||||
h = calc_tree_height(ip, size);
|
h = calc_tree_height(ip, size);
|
||||||
if (ip->i_di.di_height < h) {
|
if (ip->i_di.di_height < h) {
|
||||||
down_write(&ip->i_rw_mutex);
|
down_write(&ip->i_rw_mutex);
|
||||||
error = build_height(ip->i_vnode, h);
|
error = build_height(&ip->i_inode, h);
|
||||||
up_write(&ip->i_rw_mutex);
|
up_write(&ip->i_rw_mutex);
|
||||||
if (error)
|
if (error)
|
||||||
goto out_end_trans;
|
goto out_end_trans;
|
||||||
|
@ -830,7 +830,7 @@ static int do_grow(struct gfs2_inode *ip, uint64_t size)
|
||||||
|
|
||||||
static int trunc_start(struct gfs2_inode *ip, uint64_t size)
|
static int trunc_start(struct gfs2_inode *ip, uint64_t size)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
||||||
struct buffer_head *dibh;
|
struct buffer_head *dibh;
|
||||||
int journaled = gfs2_is_jdata(ip);
|
int journaled = gfs2_is_jdata(ip);
|
||||||
int error;
|
int error;
|
||||||
|
@ -854,7 +854,7 @@ static int trunc_start(struct gfs2_inode *ip, uint64_t size)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (size & (uint64_t)(sdp->sd_sb.sb_bsize - 1))
|
if (size & (uint64_t)(sdp->sd_sb.sb_bsize - 1))
|
||||||
error = gfs2_block_truncate_page(ip->i_vnode->i_mapping);
|
error = gfs2_block_truncate_page(ip->i_inode.i_mapping);
|
||||||
|
|
||||||
if (!error) {
|
if (!error) {
|
||||||
ip->i_di.di_size = size;
|
ip->i_di.di_size = size;
|
||||||
|
@ -883,7 +883,7 @@ static int trunc_dealloc(struct gfs2_inode *ip, uint64_t size)
|
||||||
if (!size)
|
if (!size)
|
||||||
lblock = 0;
|
lblock = 0;
|
||||||
else
|
else
|
||||||
lblock = (size - 1) >> ip->i_sbd->sd_sb.sb_bsize_shift;
|
lblock = (size - 1) >> GFS2_SB(&ip->i_inode)->sd_sb.sb_bsize_shift;
|
||||||
|
|
||||||
find_metapath(ip, lblock, &mp);
|
find_metapath(ip, lblock, &mp);
|
||||||
gfs2_alloc_get(ip);
|
gfs2_alloc_get(ip);
|
||||||
|
@ -911,7 +911,7 @@ static int trunc_dealloc(struct gfs2_inode *ip, uint64_t size)
|
||||||
|
|
||||||
static int trunc_end(struct gfs2_inode *ip)
|
static int trunc_end(struct gfs2_inode *ip)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
||||||
struct buffer_head *dibh;
|
struct buffer_head *dibh;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
@ -990,7 +990,7 @@ int gfs2_truncatei(struct gfs2_inode *ip, uint64_t size)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
if (gfs2_assert_warn(ip->i_sbd, S_ISREG(ip->i_di.di_mode)))
|
if (gfs2_assert_warn(GFS2_SB(&ip->i_inode), S_ISREG(ip->i_di.di_mode)))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (size > ip->i_di.di_size)
|
if (size > ip->i_di.di_size)
|
||||||
|
@ -1027,7 +1027,7 @@ int gfs2_file_dealloc(struct gfs2_inode *ip)
|
||||||
void gfs2_write_calc_reserv(struct gfs2_inode *ip, unsigned int len,
|
void gfs2_write_calc_reserv(struct gfs2_inode *ip, unsigned int len,
|
||||||
unsigned int *data_blocks, unsigned int *ind_blocks)
|
unsigned int *data_blocks, unsigned int *ind_blocks)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
||||||
unsigned int tmp;
|
unsigned int tmp;
|
||||||
|
|
||||||
if (gfs2_is_dir(ip)) {
|
if (gfs2_is_dir(ip)) {
|
||||||
|
@ -1057,7 +1057,7 @@ void gfs2_write_calc_reserv(struct gfs2_inode *ip, unsigned int len,
|
||||||
int gfs2_write_alloc_required(struct gfs2_inode *ip, uint64_t offset,
|
int gfs2_write_alloc_required(struct gfs2_inode *ip, uint64_t offset,
|
||||||
unsigned int len, int *alloc_required)
|
unsigned int len, int *alloc_required)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
||||||
uint64_t lblock, lblock_stop, dblock;
|
uint64_t lblock, lblock_stop, dblock;
|
||||||
uint32_t extlen;
|
uint32_t extlen;
|
||||||
int new = 0;
|
int new = 0;
|
||||||
|
@ -1088,7 +1088,7 @@ int gfs2_write_alloc_required(struct gfs2_inode *ip, uint64_t offset,
|
||||||
}
|
}
|
||||||
|
|
||||||
for (; lblock < lblock_stop; lblock += extlen) {
|
for (; lblock < lblock_stop; lblock += extlen) {
|
||||||
error = gfs2_extent_map(ip->i_vnode, lblock, &new, &dblock, &extlen);
|
error = gfs2_extent_map(&ip->i_inode, lblock, &new, &dblock, &extlen);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
#include "quota.h"
|
#include "quota.h"
|
||||||
#include "recovery.h"
|
#include "recovery.h"
|
||||||
#include "super.h"
|
#include "super.h"
|
||||||
#include "unlinked.h"
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
/* This uses schedule_timeout() instead of msleep() because it's good for
|
/* This uses schedule_timeout() instead of msleep() because it's good for
|
||||||
|
@ -195,29 +194,3 @@ int gfs2_quotad(void *data)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* gfs2_inoded - Deallocate unlinked inodes
|
|
||||||
* @sdp: Pointer to GFS2 superblock
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
int gfs2_inoded(void *data)
|
|
||||||
{
|
|
||||||
struct gfs2_sbd *sdp = data;
|
|
||||||
unsigned long t;
|
|
||||||
int error;
|
|
||||||
|
|
||||||
while (!kthread_should_stop()) {
|
|
||||||
error = gfs2_unlinked_dealloc(sdp);
|
|
||||||
if (error &&
|
|
||||||
error != -EROFS &&
|
|
||||||
!test_bit(SDF_SHUTDOWN, &sdp->sd_flags))
|
|
||||||
fs_err(sdp, "inoded: error = %d\n", error);
|
|
||||||
|
|
||||||
t = gfs2_tune_get(sdp, gt_inoded_secs) * HZ;
|
|
||||||
schedule_timeout_interruptible(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,5 @@ int gfs2_glockd(void *data);
|
||||||
int gfs2_recoverd(void *data);
|
int gfs2_recoverd(void *data);
|
||||||
int gfs2_logd(void *data);
|
int gfs2_logd(void *data);
|
||||||
int gfs2_quotad(void *data);
|
int gfs2_quotad(void *data);
|
||||||
int gfs2_inoded(void *data);
|
|
||||||
|
|
||||||
#endif /* __DAEMON_DOT_H__ */
|
#endif /* __DAEMON_DOT_H__ */
|
||||||
|
|
|
@ -113,7 +113,7 @@ static int gfs2_dir_get_existing_buffer(struct gfs2_inode *ip, uint64_t block,
|
||||||
error = gfs2_meta_read(ip->i_gl, block, DIO_START | DIO_WAIT, &bh);
|
error = gfs2_meta_read(ip->i_gl, block, DIO_START | DIO_WAIT, &bh);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
if (gfs2_metatype_check(ip->i_sbd, bh, GFS2_METATYPE_JD)) {
|
if (gfs2_metatype_check(GFS2_SB(&ip->i_inode), bh, GFS2_METATYPE_JD)) {
|
||||||
brelse(bh);
|
brelse(bh);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
@ -158,7 +158,7 @@ static int gfs2_dir_write_stuffed(struct gfs2_inode *ip, const char *buf,
|
||||||
static int gfs2_dir_write_data(struct gfs2_inode *ip, const char *buf,
|
static int gfs2_dir_write_data(struct gfs2_inode *ip, const char *buf,
|
||||||
uint64_t offset, unsigned int size)
|
uint64_t offset, unsigned int size)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
||||||
struct buffer_head *dibh;
|
struct buffer_head *dibh;
|
||||||
uint64_t lblock, dblock;
|
uint64_t lblock, dblock;
|
||||||
uint32_t extlen = 0;
|
uint32_t extlen = 0;
|
||||||
|
@ -197,7 +197,7 @@ static int gfs2_dir_write_data(struct gfs2_inode *ip, const char *buf,
|
||||||
|
|
||||||
if (!extlen) {
|
if (!extlen) {
|
||||||
new = 1;
|
new = 1;
|
||||||
error = gfs2_extent_map(ip->i_vnode, lblock, &new,
|
error = gfs2_extent_map(&ip->i_inode, lblock, &new,
|
||||||
&dblock, &extlen);
|
&dblock, &extlen);
|
||||||
if (error)
|
if (error)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -277,7 +277,7 @@ static int gfs2_dir_read_stuffed(struct gfs2_inode *ip, char *buf,
|
||||||
static int gfs2_dir_read_data(struct gfs2_inode *ip, char *buf,
|
static int gfs2_dir_read_data(struct gfs2_inode *ip, char *buf,
|
||||||
uint64_t offset, unsigned int size)
|
uint64_t offset, unsigned int size)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
||||||
uint64_t lblock, dblock;
|
uint64_t lblock, dblock;
|
||||||
uint32_t extlen = 0;
|
uint32_t extlen = 0;
|
||||||
unsigned int o;
|
unsigned int o;
|
||||||
|
@ -314,7 +314,7 @@ static int gfs2_dir_read_data(struct gfs2_inode *ip, char *buf,
|
||||||
|
|
||||||
if (!extlen) {
|
if (!extlen) {
|
||||||
new = 0;
|
new = 0;
|
||||||
error = gfs2_extent_map(ip->i_vnode, lblock, &new,
|
error = gfs2_extent_map(&ip->i_inode, lblock, &new,
|
||||||
&dblock, &extlen);
|
&dblock, &extlen);
|
||||||
if (error)
|
if (error)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -534,7 +534,7 @@ static struct gfs2_dirent *gfs2_dirent_scan(struct inode *inode,
|
||||||
}
|
}
|
||||||
|
|
||||||
consist_inode:
|
consist_inode:
|
||||||
gfs2_consist_inode(inode->u.generic_ip);
|
gfs2_consist_inode(GFS2_I(inode));
|
||||||
return ERR_PTR(-EIO);
|
return ERR_PTR(-EIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -556,13 +556,13 @@ static int dirent_first(struct gfs2_inode *dip, struct buffer_head *bh,
|
||||||
struct gfs2_meta_header *h = (struct gfs2_meta_header *)bh->b_data;
|
struct gfs2_meta_header *h = (struct gfs2_meta_header *)bh->b_data;
|
||||||
|
|
||||||
if (be32_to_cpu(h->mh_type) == GFS2_METATYPE_LF) {
|
if (be32_to_cpu(h->mh_type) == GFS2_METATYPE_LF) {
|
||||||
if (gfs2_meta_check(dip->i_sbd, bh))
|
if (gfs2_meta_check(GFS2_SB(&dip->i_inode), bh))
|
||||||
return -EIO;
|
return -EIO;
|
||||||
*dent = (struct gfs2_dirent *)(bh->b_data +
|
*dent = (struct gfs2_dirent *)(bh->b_data +
|
||||||
sizeof(struct gfs2_leaf));
|
sizeof(struct gfs2_leaf));
|
||||||
return IS_LEAF;
|
return IS_LEAF;
|
||||||
} else {
|
} else {
|
||||||
if (gfs2_metatype_check(dip->i_sbd, bh, GFS2_METATYPE_DI))
|
if (gfs2_metatype_check(GFS2_SB(&dip->i_inode), bh, GFS2_METATYPE_DI))
|
||||||
return -EIO;
|
return -EIO;
|
||||||
*dent = (struct gfs2_dirent *)(bh->b_data +
|
*dent = (struct gfs2_dirent *)(bh->b_data +
|
||||||
sizeof(struct gfs2_dinode));
|
sizeof(struct gfs2_dinode));
|
||||||
|
@ -674,7 +674,7 @@ static struct gfs2_dirent *gfs2_init_dirent(struct inode *inode,
|
||||||
const struct qstr *name,
|
const struct qstr *name,
|
||||||
struct buffer_head *bh)
|
struct buffer_head *bh)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(inode);
|
||||||
struct gfs2_dirent *ndent;
|
struct gfs2_dirent *ndent;
|
||||||
unsigned offset = 0, totlen;
|
unsigned offset = 0, totlen;
|
||||||
|
|
||||||
|
@ -707,8 +707,10 @@ static int get_leaf(struct gfs2_inode *dip, uint64_t leaf_no,
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
error = gfs2_meta_read(dip->i_gl, leaf_no, DIO_START | DIO_WAIT, bhp);
|
error = gfs2_meta_read(dip->i_gl, leaf_no, DIO_START | DIO_WAIT, bhp);
|
||||||
if (!error && gfs2_metatype_check(dip->i_sbd, *bhp, GFS2_METATYPE_LF))
|
if (!error && gfs2_metatype_check(GFS2_SB(&dip->i_inode), *bhp, GFS2_METATYPE_LF)) {
|
||||||
|
/* printk(KERN_INFO "block num=%llu\n", leaf_no); */
|
||||||
error = -EIO;
|
error = -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
@ -759,7 +761,7 @@ static struct gfs2_dirent *gfs2_dirent_search(struct inode *inode,
|
||||||
{
|
{
|
||||||
struct buffer_head *bh;
|
struct buffer_head *bh;
|
||||||
struct gfs2_dirent *dent;
|
struct gfs2_dirent *dent;
|
||||||
struct gfs2_inode *ip = inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(inode);
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
if (ip->i_di.di_flags & GFS2_DIF_EXHASH) {
|
if (ip->i_di.di_flags & GFS2_DIF_EXHASH) {
|
||||||
|
@ -771,7 +773,7 @@ static struct gfs2_dirent *gfs2_dirent_search(struct inode *inode,
|
||||||
gfs2_consist_inode(ip);
|
gfs2_consist_inode(ip);
|
||||||
return ERR_PTR(-EIO);
|
return ERR_PTR(-EIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
index = name->hash >> (32 - ip->i_di.di_depth);
|
index = name->hash >> (32 - ip->i_di.di_depth);
|
||||||
error = get_first_leaf(ip, index, &bh);
|
error = get_first_leaf(ip, index, &bh);
|
||||||
if (error)
|
if (error)
|
||||||
|
@ -786,12 +788,14 @@ static struct gfs2_dirent *gfs2_dirent_search(struct inode *inode,
|
||||||
brelse(bh);
|
brelse(bh);
|
||||||
if (!ln)
|
if (!ln)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
error = get_leaf(ip, ln, &bh);
|
error = get_leaf(ip, ln, &bh);
|
||||||
} while(!error);
|
} while(!error);
|
||||||
|
|
||||||
return error ? ERR_PTR(error) : NULL;
|
return error ? ERR_PTR(error) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
error = gfs2_meta_inode_buffer(ip, &bh);
|
error = gfs2_meta_inode_buffer(ip, &bh);
|
||||||
if (error)
|
if (error)
|
||||||
return ERR_PTR(error);
|
return ERR_PTR(error);
|
||||||
|
@ -807,7 +811,7 @@ got_dent:
|
||||||
|
|
||||||
static struct gfs2_leaf *new_leaf(struct inode *inode, struct buffer_head **pbh, u16 depth)
|
static struct gfs2_leaf *new_leaf(struct inode *inode, struct buffer_head **pbh, u16 depth)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(inode);
|
||||||
u64 bn = gfs2_alloc_meta(ip);
|
u64 bn = gfs2_alloc_meta(ip);
|
||||||
struct buffer_head *bh = gfs2_meta_new(ip->i_gl, bn);
|
struct buffer_head *bh = gfs2_meta_new(ip->i_gl, bn);
|
||||||
struct gfs2_leaf *leaf;
|
struct gfs2_leaf *leaf;
|
||||||
|
@ -815,6 +819,7 @@ static struct gfs2_leaf *new_leaf(struct inode *inode, struct buffer_head **pbh,
|
||||||
struct qstr name = { .name = "", .len = 0, .hash = 0 };
|
struct qstr name = { .name = "", .len = 0, .hash = 0 };
|
||||||
if (!bh)
|
if (!bh)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
gfs2_trans_add_bh(ip->i_gl, bh, 1);
|
gfs2_trans_add_bh(ip->i_gl, bh, 1);
|
||||||
gfs2_metatype_set(bh, GFS2_METATYPE_LF, GFS2_FORMAT_LF);
|
gfs2_metatype_set(bh, GFS2_METATYPE_LF, GFS2_FORMAT_LF);
|
||||||
leaf = (struct gfs2_leaf *)bh->b_data;
|
leaf = (struct gfs2_leaf *)bh->b_data;
|
||||||
|
@ -838,8 +843,8 @@ static struct gfs2_leaf *new_leaf(struct inode *inode, struct buffer_head **pbh,
|
||||||
|
|
||||||
static int dir_make_exhash(struct inode *inode)
|
static int dir_make_exhash(struct inode *inode)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *dip = inode->u.generic_ip;
|
struct gfs2_inode *dip = GFS2_I(inode);
|
||||||
struct gfs2_sbd *sdp = dip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(inode);
|
||||||
struct gfs2_dirent *dent;
|
struct gfs2_dirent *dent;
|
||||||
struct qstr args;
|
struct qstr args;
|
||||||
struct buffer_head *bh, *dibh;
|
struct buffer_head *bh, *dibh;
|
||||||
|
@ -874,7 +879,7 @@ static int dir_make_exhash(struct inode *inode)
|
||||||
args.len = bh->b_size - sizeof(struct gfs2_dinode) +
|
args.len = bh->b_size - sizeof(struct gfs2_dinode) +
|
||||||
sizeof(struct gfs2_leaf);
|
sizeof(struct gfs2_leaf);
|
||||||
args.name = bh->b_data;
|
args.name = bh->b_data;
|
||||||
dent = gfs2_dirent_scan(dip->i_vnode, bh->b_data, bh->b_size,
|
dent = gfs2_dirent_scan(&dip->i_inode, bh->b_data, bh->b_size,
|
||||||
gfs2_dirent_last, &args, NULL);
|
gfs2_dirent_last, &args, NULL);
|
||||||
if (!dent) {
|
if (!dent) {
|
||||||
brelse(bh);
|
brelse(bh);
|
||||||
|
@ -933,7 +938,7 @@ static int dir_make_exhash(struct inode *inode)
|
||||||
|
|
||||||
static int dir_split_leaf(struct inode *inode, const struct qstr *name)
|
static int dir_split_leaf(struct inode *inode, const struct qstr *name)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *dip = inode->u.generic_ip;
|
struct gfs2_inode *dip = GFS2_I(inode);
|
||||||
struct buffer_head *nbh, *obh, *dibh;
|
struct buffer_head *nbh, *obh, *dibh;
|
||||||
struct gfs2_leaf *nleaf, *oleaf;
|
struct gfs2_leaf *nleaf, *oleaf;
|
||||||
struct gfs2_dirent *dent, *prev = NULL, *next = NULL, *new;
|
struct gfs2_dirent *dent, *prev = NULL, *next = NULL, *new;
|
||||||
|
@ -1044,7 +1049,7 @@ static int dir_split_leaf(struct inode *inode, const struct qstr *name)
|
||||||
oleaf->lf_depth = nleaf->lf_depth;
|
oleaf->lf_depth = nleaf->lf_depth;
|
||||||
|
|
||||||
error = gfs2_meta_inode_buffer(dip, &dibh);
|
error = gfs2_meta_inode_buffer(dip, &dibh);
|
||||||
if (!gfs2_assert_withdraw(dip->i_sbd, !error)) {
|
if (!gfs2_assert_withdraw(GFS2_SB(&dip->i_inode), !error)) {
|
||||||
dip->i_di.di_blocks++;
|
dip->i_di.di_blocks++;
|
||||||
gfs2_dinode_out(&dip->i_di, dibh->b_data);
|
gfs2_dinode_out(&dip->i_di, dibh->b_data);
|
||||||
brelse(dibh);
|
brelse(dibh);
|
||||||
|
@ -1073,7 +1078,7 @@ fail_brelse:
|
||||||
|
|
||||||
static int dir_double_exhash(struct gfs2_inode *dip)
|
static int dir_double_exhash(struct gfs2_inode *dip)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = dip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
|
||||||
struct buffer_head *dibh;
|
struct buffer_head *dibh;
|
||||||
uint32_t hsize;
|
uint32_t hsize;
|
||||||
uint64_t *buf;
|
uint64_t *buf;
|
||||||
|
@ -1268,7 +1273,7 @@ static int gfs2_dir_read_leaf(struct inode *inode, u64 *offset, void *opaque,
|
||||||
gfs2_filldir_t filldir, int *copied,
|
gfs2_filldir_t filldir, int *copied,
|
||||||
unsigned *depth, u64 leaf_no)
|
unsigned *depth, u64 leaf_no)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(inode);
|
||||||
struct buffer_head *bh;
|
struct buffer_head *bh;
|
||||||
struct gfs2_leaf *lf;
|
struct gfs2_leaf *lf;
|
||||||
unsigned entries = 0;
|
unsigned entries = 0;
|
||||||
|
@ -1348,8 +1353,8 @@ out:
|
||||||
static int dir_e_read(struct inode *inode, uint64_t *offset, void *opaque,
|
static int dir_e_read(struct inode *inode, uint64_t *offset, void *opaque,
|
||||||
gfs2_filldir_t filldir)
|
gfs2_filldir_t filldir)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *dip = inode->u.generic_ip;
|
struct gfs2_inode *dip = GFS2_I(inode);
|
||||||
struct gfs2_sbd *sdp = dip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(inode);
|
||||||
uint32_t hsize, len = 0;
|
uint32_t hsize, len = 0;
|
||||||
uint32_t ht_offset, lp_offset, ht_offset_cur = -1;
|
uint32_t ht_offset, lp_offset, ht_offset_cur = -1;
|
||||||
uint32_t hash, index;
|
uint32_t hash, index;
|
||||||
|
@ -1407,7 +1412,7 @@ out:
|
||||||
int gfs2_dir_read(struct inode *inode, uint64_t *offset, void *opaque,
|
int gfs2_dir_read(struct inode *inode, uint64_t *offset, void *opaque,
|
||||||
gfs2_filldir_t filldir)
|
gfs2_filldir_t filldir)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *dip = inode->u.generic_ip;
|
struct gfs2_inode *dip = GFS2_I(inode);
|
||||||
struct dirent_gather g;
|
struct dirent_gather g;
|
||||||
const struct gfs2_dirent **darr, *dent;
|
const struct gfs2_dirent **darr, *dent;
|
||||||
struct buffer_head *dibh;
|
struct buffer_head *dibh;
|
||||||
|
@ -1490,7 +1495,7 @@ int gfs2_dir_search(struct inode *dir, const struct qstr *name,
|
||||||
static int dir_new_leaf(struct inode *inode, const struct qstr *name)
|
static int dir_new_leaf(struct inode *inode, const struct qstr *name)
|
||||||
{
|
{
|
||||||
struct buffer_head *bh, *obh;
|
struct buffer_head *bh, *obh;
|
||||||
struct gfs2_inode *ip = inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(inode);
|
||||||
struct gfs2_leaf *leaf, *oleaf;
|
struct gfs2_leaf *leaf, *oleaf;
|
||||||
int error;
|
int error;
|
||||||
u32 index;
|
u32 index;
|
||||||
|
@ -1545,7 +1550,7 @@ static int dir_new_leaf(struct inode *inode, const struct qstr *name)
|
||||||
int gfs2_dir_add(struct inode *inode, const struct qstr *name,
|
int gfs2_dir_add(struct inode *inode, const struct qstr *name,
|
||||||
const struct gfs2_inum *inum, unsigned type)
|
const struct gfs2_inum *inum, unsigned type)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(inode);
|
||||||
struct buffer_head *bh;
|
struct buffer_head *bh;
|
||||||
struct gfs2_dirent *dent;
|
struct gfs2_dirent *dent;
|
||||||
struct gfs2_leaf *leaf;
|
struct gfs2_leaf *leaf;
|
||||||
|
@ -1623,7 +1628,7 @@ int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *name)
|
||||||
|
|
||||||
/* Returns _either_ the entry (if its first in block) or the
|
/* Returns _either_ the entry (if its first in block) or the
|
||||||
previous entry otherwise */
|
previous entry otherwise */
|
||||||
dent = gfs2_dirent_search(dip->i_vnode, name, gfs2_dirent_prev, &bh);
|
dent = gfs2_dirent_search(&dip->i_inode, name, gfs2_dirent_prev, &bh);
|
||||||
if (!dent) {
|
if (!dent) {
|
||||||
gfs2_consist_inode(dip);
|
gfs2_consist_inode(dip);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
@ -1659,6 +1664,7 @@ int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *name)
|
||||||
dip->i_di.di_mtime = dip->i_di.di_ctime = get_seconds();
|
dip->i_di.di_mtime = dip->i_di.di_ctime = get_seconds();
|
||||||
gfs2_dinode_out(&dip->i_di, bh->b_data);
|
gfs2_dinode_out(&dip->i_di, bh->b_data);
|
||||||
brelse(bh);
|
brelse(bh);
|
||||||
|
mark_inode_dirty(&dip->i_inode);
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
@ -1683,7 +1689,7 @@ int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
|
||||||
struct gfs2_dirent *dent;
|
struct gfs2_dirent *dent;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
dent = gfs2_dirent_search(dip->i_vnode, filename, gfs2_dirent_find, &bh);
|
dent = gfs2_dirent_search(&dip->i_inode, filename, gfs2_dirent_find, &bh);
|
||||||
if (!dent) {
|
if (!dent) {
|
||||||
gfs2_consist_inode(dip);
|
gfs2_consist_inode(dip);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
@ -1720,7 +1726,7 @@ int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
|
||||||
|
|
||||||
static int foreach_leaf(struct gfs2_inode *dip, leaf_call_t lc, void *data)
|
static int foreach_leaf(struct gfs2_inode *dip, leaf_call_t lc, void *data)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = dip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
|
||||||
struct buffer_head *bh;
|
struct buffer_head *bh;
|
||||||
struct gfs2_leaf *leaf;
|
struct gfs2_leaf *leaf;
|
||||||
uint32_t hsize, len;
|
uint32_t hsize, len;
|
||||||
|
@ -1800,7 +1806,7 @@ static int foreach_leaf(struct gfs2_inode *dip, leaf_call_t lc, void *data)
|
||||||
static int leaf_dealloc(struct gfs2_inode *dip, uint32_t index, uint32_t len,
|
static int leaf_dealloc(struct gfs2_inode *dip, uint32_t index, uint32_t len,
|
||||||
uint64_t leaf_no, void *data)
|
uint64_t leaf_no, void *data)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = dip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
|
||||||
struct gfs2_leaf *tmp_leaf;
|
struct gfs2_leaf *tmp_leaf;
|
||||||
struct gfs2_rgrp_list rlist;
|
struct gfs2_rgrp_list rlist;
|
||||||
struct buffer_head *bh, *dibh;
|
struct buffer_head *bh, *dibh;
|
||||||
|
@ -1920,7 +1926,7 @@ static int leaf_dealloc(struct gfs2_inode *dip, uint32_t index, uint32_t len,
|
||||||
|
|
||||||
int gfs2_dir_exhash_dealloc(struct gfs2_inode *dip)
|
int gfs2_dir_exhash_dealloc(struct gfs2_inode *dip)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = dip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
|
||||||
struct buffer_head *bh;
|
struct buffer_head *bh;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@ unsigned int gfs2_ea_name2type(const char *name, char **truncated_name)
|
||||||
|
|
||||||
static int user_eo_get(struct gfs2_inode *ip, struct gfs2_ea_request *er)
|
static int user_eo_get(struct gfs2_inode *ip, struct gfs2_ea_request *er)
|
||||||
{
|
{
|
||||||
struct inode *inode = ip->i_vnode;
|
struct inode *inode = &ip->i_inode;
|
||||||
int error = permission(inode, MAY_READ, NULL);
|
int error = permission(inode, MAY_READ, NULL);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
@ -68,7 +68,7 @@ static int user_eo_get(struct gfs2_inode *ip, struct gfs2_ea_request *er)
|
||||||
|
|
||||||
static int user_eo_set(struct gfs2_inode *ip, struct gfs2_ea_request *er)
|
static int user_eo_set(struct gfs2_inode *ip, struct gfs2_ea_request *er)
|
||||||
{
|
{
|
||||||
struct inode *inode = ip->i_vnode;
|
struct inode *inode = &ip->i_inode;
|
||||||
|
|
||||||
if (S_ISREG(inode->i_mode) ||
|
if (S_ISREG(inode->i_mode) ||
|
||||||
(S_ISDIR(inode->i_mode) && !(inode->i_mode & S_ISVTX))) {
|
(S_ISDIR(inode->i_mode) && !(inode->i_mode & S_ISVTX))) {
|
||||||
|
@ -83,7 +83,7 @@ static int user_eo_set(struct gfs2_inode *ip, struct gfs2_ea_request *er)
|
||||||
|
|
||||||
static int user_eo_remove(struct gfs2_inode *ip, struct gfs2_ea_request *er)
|
static int user_eo_remove(struct gfs2_inode *ip, struct gfs2_ea_request *er)
|
||||||
{
|
{
|
||||||
struct inode *inode = ip->i_vnode;
|
struct inode *inode = &ip->i_inode;
|
||||||
|
|
||||||
if (S_ISREG(inode->i_mode) ||
|
if (S_ISREG(inode->i_mode) ||
|
||||||
(S_ISDIR(inode->i_mode) && !(inode->i_mode & S_ISVTX))) {
|
(S_ISDIR(inode->i_mode) && !(inode->i_mode & S_ISVTX))) {
|
||||||
|
@ -103,7 +103,7 @@ static int system_eo_get(struct gfs2_inode *ip, struct gfs2_ea_request *er)
|
||||||
!capable(CAP_SYS_ADMIN))
|
!capable(CAP_SYS_ADMIN))
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
||||||
if (ip->i_sbd->sd_args.ar_posix_acl == 0 &&
|
if (GFS2_SB(&ip->i_inode)->sd_args.ar_posix_acl == 0 &&
|
||||||
(GFS2_ACL_IS_ACCESS(er->er_name, er->er_name_len) ||
|
(GFS2_ACL_IS_ACCESS(er->er_name, er->er_name_len) ||
|
||||||
GFS2_ACL_IS_DEFAULT(er->er_name, er->er_name_len)))
|
GFS2_ACL_IS_DEFAULT(er->er_name, er->er_name_len)))
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
@ -172,7 +172,7 @@ static int system_eo_remove(struct gfs2_inode *ip, struct gfs2_ea_request *er)
|
||||||
|
|
||||||
static int security_eo_get(struct gfs2_inode *ip, struct gfs2_ea_request *er)
|
static int security_eo_get(struct gfs2_inode *ip, struct gfs2_ea_request *er)
|
||||||
{
|
{
|
||||||
struct inode *inode = ip->i_vnode;
|
struct inode *inode = &ip->i_inode;
|
||||||
int error = permission(inode, MAY_READ, NULL);
|
int error = permission(inode, MAY_READ, NULL);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
@ -182,7 +182,7 @@ static int security_eo_get(struct gfs2_inode *ip, struct gfs2_ea_request *er)
|
||||||
|
|
||||||
static int security_eo_set(struct gfs2_inode *ip, struct gfs2_ea_request *er)
|
static int security_eo_set(struct gfs2_inode *ip, struct gfs2_ea_request *er)
|
||||||
{
|
{
|
||||||
struct inode *inode = ip->i_vnode;
|
struct inode *inode = &ip->i_inode;
|
||||||
int error = permission(inode, MAY_WRITE, NULL);
|
int error = permission(inode, MAY_WRITE, NULL);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
@ -192,7 +192,7 @@ static int security_eo_set(struct gfs2_inode *ip, struct gfs2_ea_request *er)
|
||||||
|
|
||||||
static int security_eo_remove(struct gfs2_inode *ip, struct gfs2_ea_request *er)
|
static int security_eo_remove(struct gfs2_inode *ip, struct gfs2_ea_request *er)
|
||||||
{
|
{
|
||||||
struct inode *inode = ip->i_vnode;
|
struct inode *inode = &ip->i_inode;
|
||||||
int error = permission(inode, MAY_WRITE, NULL);
|
int error = permission(inode, MAY_WRITE, NULL);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
|
|
@ -80,7 +80,7 @@ static int ea_foreach_i(struct gfs2_inode *ip, struct buffer_head *bh,
|
||||||
struct gfs2_ea_header *ea, *prev = NULL;
|
struct gfs2_ea_header *ea, *prev = NULL;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
if (gfs2_metatype_check(ip->i_sbd, bh, GFS2_METATYPE_EA))
|
if (gfs2_metatype_check(GFS2_SB(&ip->i_inode), bh, GFS2_METATYPE_EA))
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
for (ea = GFS2_EA_BH2FIRST(bh);; prev = ea, ea = GFS2_EA2NEXT(ea)) {
|
for (ea = GFS2_EA_BH2FIRST(bh);; prev = ea, ea = GFS2_EA2NEXT(ea)) {
|
||||||
|
@ -128,13 +128,13 @@ static int ea_foreach(struct gfs2_inode *ip, ea_call_t ea_call, void *data)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gfs2_metatype_check(ip->i_sbd, bh, GFS2_METATYPE_IN)) {
|
if (gfs2_metatype_check(GFS2_SB(&ip->i_inode), bh, GFS2_METATYPE_IN)) {
|
||||||
error = -EIO;
|
error = -EIO;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
eablk = (uint64_t *)(bh->b_data + sizeof(struct gfs2_meta_header));
|
eablk = (uint64_t *)(bh->b_data + sizeof(struct gfs2_meta_header));
|
||||||
end = eablk + ip->i_sbd->sd_inptrs;
|
end = eablk + GFS2_SB(&ip->i_inode)->sd_inptrs;
|
||||||
|
|
||||||
for (; eablk < end; eablk++) {
|
for (; eablk < end; eablk++) {
|
||||||
uint64_t bn;
|
uint64_t bn;
|
||||||
|
@ -232,7 +232,7 @@ static int ea_dealloc_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh,
|
||||||
struct gfs2_ea_header *prev, void *private)
|
struct gfs2_ea_header *prev, void *private)
|
||||||
{
|
{
|
||||||
int *leave = private;
|
int *leave = private;
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
||||||
struct gfs2_rgrpd *rgd;
|
struct gfs2_rgrpd *rgd;
|
||||||
struct gfs2_holder rg_gh;
|
struct gfs2_holder rg_gh;
|
||||||
struct buffer_head *dibh;
|
struct buffer_head *dibh;
|
||||||
|
@ -338,7 +338,7 @@ static int ea_remove_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh,
|
||||||
if (error)
|
if (error)
|
||||||
goto out_alloc;
|
goto out_alloc;
|
||||||
|
|
||||||
error = gfs2_rindex_hold(ip->i_sbd, &al->al_ri_gh);
|
error = gfs2_rindex_hold(GFS2_SB(&ip->i_inode), &al->al_ri_gh);
|
||||||
if (error)
|
if (error)
|
||||||
goto out_quota;
|
goto out_quota;
|
||||||
|
|
||||||
|
@ -459,7 +459,7 @@ int gfs2_ea_list(struct gfs2_inode *ip, struct gfs2_ea_request *er)
|
||||||
static int ea_get_unstuffed(struct gfs2_inode *ip, struct gfs2_ea_header *ea,
|
static int ea_get_unstuffed(struct gfs2_inode *ip, struct gfs2_ea_header *ea,
|
||||||
char *data)
|
char *data)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
||||||
struct buffer_head **bh;
|
struct buffer_head **bh;
|
||||||
unsigned int amount = GFS2_EA_DATA_LEN(ea);
|
unsigned int amount = GFS2_EA_DATA_LEN(ea);
|
||||||
unsigned int nptrs = DIV_ROUND_UP(amount, sdp->sd_jbsize);
|
unsigned int nptrs = DIV_ROUND_UP(amount, sdp->sd_jbsize);
|
||||||
|
@ -604,7 +604,7 @@ int gfs2_ea_get(struct gfs2_inode *ip, struct gfs2_ea_request *er)
|
||||||
|
|
||||||
static int ea_alloc_blk(struct gfs2_inode *ip, struct buffer_head **bhp)
|
static int ea_alloc_blk(struct gfs2_inode *ip, struct buffer_head **bhp)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
||||||
struct gfs2_ea_header *ea;
|
struct gfs2_ea_header *ea;
|
||||||
uint64_t block;
|
uint64_t block;
|
||||||
|
|
||||||
|
@ -641,7 +641,7 @@ static int ea_alloc_blk(struct gfs2_inode *ip, struct buffer_head **bhp)
|
||||||
static int ea_write(struct gfs2_inode *ip, struct gfs2_ea_header *ea,
|
static int ea_write(struct gfs2_inode *ip, struct gfs2_ea_header *ea,
|
||||||
struct gfs2_ea_request *er)
|
struct gfs2_ea_request *er)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
||||||
|
|
||||||
ea->ea_data_len = cpu_to_be32(er->er_data_len);
|
ea->ea_data_len = cpu_to_be32(er->er_data_len);
|
||||||
ea->ea_name_len = er->er_name_len;
|
ea->ea_name_len = er->er_name_len;
|
||||||
|
@ -723,7 +723,7 @@ static int ea_alloc_skeleton(struct gfs2_inode *ip, struct gfs2_ea_request *er,
|
||||||
if (error)
|
if (error)
|
||||||
goto out_gunlock_q;
|
goto out_gunlock_q;
|
||||||
|
|
||||||
error = gfs2_trans_begin(ip->i_sbd,
|
error = gfs2_trans_begin(GFS2_SB(&ip->i_inode),
|
||||||
blks + al->al_rgd->rd_ri.ri_length +
|
blks + al->al_rgd->rd_ri.ri_length +
|
||||||
RES_DINODE + RES_STATFS + RES_QUOTA, 0);
|
RES_DINODE + RES_STATFS + RES_QUOTA, 0);
|
||||||
if (error)
|
if (error)
|
||||||
|
@ -736,7 +736,7 @@ static int ea_alloc_skeleton(struct gfs2_inode *ip, struct gfs2_ea_request *er,
|
||||||
error = gfs2_meta_inode_buffer(ip, &dibh);
|
error = gfs2_meta_inode_buffer(ip, &dibh);
|
||||||
if (!error) {
|
if (!error) {
|
||||||
if (er->er_flags & GFS2_ERF_MODE) {
|
if (er->er_flags & GFS2_ERF_MODE) {
|
||||||
gfs2_assert_withdraw(ip->i_sbd,
|
gfs2_assert_withdraw(GFS2_SB(&ip->i_inode),
|
||||||
(ip->i_di.di_mode & S_IFMT) ==
|
(ip->i_di.di_mode & S_IFMT) ==
|
||||||
(er->er_mode & S_IFMT));
|
(er->er_mode & S_IFMT));
|
||||||
ip->i_di.di_mode = er->er_mode;
|
ip->i_di.di_mode = er->er_mode;
|
||||||
|
@ -748,7 +748,7 @@ static int ea_alloc_skeleton(struct gfs2_inode *ip, struct gfs2_ea_request *er,
|
||||||
}
|
}
|
||||||
|
|
||||||
out_end_trans:
|
out_end_trans:
|
||||||
gfs2_trans_end(ip->i_sbd);
|
gfs2_trans_end(GFS2_SB(&ip->i_inode));
|
||||||
|
|
||||||
out_ipres:
|
out_ipres:
|
||||||
gfs2_inplace_release(ip);
|
gfs2_inplace_release(ip);
|
||||||
|
@ -790,7 +790,7 @@ static int ea_init_i(struct gfs2_inode *ip, struct gfs2_ea_request *er,
|
||||||
|
|
||||||
static int ea_init(struct gfs2_inode *ip, struct gfs2_ea_request *er)
|
static int ea_init(struct gfs2_inode *ip, struct gfs2_ea_request *er)
|
||||||
{
|
{
|
||||||
unsigned int jbsize = ip->i_sbd->sd_jbsize;
|
unsigned int jbsize = GFS2_SB(&ip->i_inode)->sd_jbsize;
|
||||||
unsigned int blks = 1;
|
unsigned int blks = 1;
|
||||||
|
|
||||||
if (GFS2_EAREQ_SIZE_STUFFED(er) > jbsize)
|
if (GFS2_EAREQ_SIZE_STUFFED(er) > jbsize)
|
||||||
|
@ -830,7 +830,7 @@ static void ea_set_remove_stuffed(struct gfs2_inode *ip,
|
||||||
return;
|
return;
|
||||||
} else if (GFS2_EA2NEXT(prev) != ea) {
|
} else if (GFS2_EA2NEXT(prev) != ea) {
|
||||||
prev = GFS2_EA2NEXT(prev);
|
prev = GFS2_EA2NEXT(prev);
|
||||||
gfs2_assert_withdraw(ip->i_sbd, GFS2_EA2NEXT(prev) == ea);
|
gfs2_assert_withdraw(GFS2_SB(&ip->i_inode), GFS2_EA2NEXT(prev) == ea);
|
||||||
}
|
}
|
||||||
|
|
||||||
len = GFS2_EA_REC_LEN(prev) + GFS2_EA_REC_LEN(ea);
|
len = GFS2_EA_REC_LEN(prev) + GFS2_EA_REC_LEN(ea);
|
||||||
|
@ -857,7 +857,7 @@ static int ea_set_simple_noalloc(struct gfs2_inode *ip, struct buffer_head *bh,
|
||||||
struct buffer_head *dibh;
|
struct buffer_head *dibh;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
error = gfs2_trans_begin(ip->i_sbd, RES_DINODE + 2 * RES_EATTR, 0);
|
error = gfs2_trans_begin(GFS2_SB(&ip->i_inode), RES_DINODE + 2 * RES_EATTR, 0);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
|
@ -876,7 +876,7 @@ static int ea_set_simple_noalloc(struct gfs2_inode *ip, struct buffer_head *bh,
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (er->er_flags & GFS2_ERF_MODE) {
|
if (er->er_flags & GFS2_ERF_MODE) {
|
||||||
gfs2_assert_withdraw(ip->i_sbd,
|
gfs2_assert_withdraw(GFS2_SB(&ip->i_inode),
|
||||||
(ip->i_di.di_mode & S_IFMT) == (er->er_mode & S_IFMT));
|
(ip->i_di.di_mode & S_IFMT) == (er->er_mode & S_IFMT));
|
||||||
ip->i_di.di_mode = er->er_mode;
|
ip->i_di.di_mode = er->er_mode;
|
||||||
}
|
}
|
||||||
|
@ -885,7 +885,7 @@ static int ea_set_simple_noalloc(struct gfs2_inode *ip, struct buffer_head *bh,
|
||||||
gfs2_dinode_out(&ip->i_di, dibh->b_data);
|
gfs2_dinode_out(&ip->i_di, dibh->b_data);
|
||||||
brelse(dibh);
|
brelse(dibh);
|
||||||
out:
|
out:
|
||||||
gfs2_trans_end(ip->i_sbd);
|
gfs2_trans_end(GFS2_SB(&ip->i_inode));
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
@ -921,7 +921,7 @@ static int ea_set_simple(struct gfs2_inode *ip, struct buffer_head *bh,
|
||||||
int stuffed;
|
int stuffed;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
stuffed = ea_calc_size(ip->i_sbd, es->es_er, &size);
|
stuffed = ea_calc_size(GFS2_SB(&ip->i_inode), es->es_er, &size);
|
||||||
|
|
||||||
if (ea->ea_type == GFS2_EATYPE_UNUSED) {
|
if (ea->ea_type == GFS2_EATYPE_UNUSED) {
|
||||||
if (GFS2_EA_REC_LEN(ea) < size)
|
if (GFS2_EA_REC_LEN(ea) < size)
|
||||||
|
@ -947,7 +947,7 @@ static int ea_set_simple(struct gfs2_inode *ip, struct buffer_head *bh,
|
||||||
es->es_bh = bh;
|
es->es_bh = bh;
|
||||||
es->es_ea = ea;
|
es->es_ea = ea;
|
||||||
blks = 2 + DIV_ROUND_UP(es->es_er->er_data_len,
|
blks = 2 + DIV_ROUND_UP(es->es_er->er_data_len,
|
||||||
ip->i_sbd->sd_jbsize);
|
GFS2_SB(&ip->i_inode)->sd_jbsize);
|
||||||
|
|
||||||
error = ea_alloc_skeleton(ip, es->es_er, blks,
|
error = ea_alloc_skeleton(ip, es->es_er, blks,
|
||||||
ea_set_simple_alloc, es);
|
ea_set_simple_alloc, es);
|
||||||
|
@ -961,7 +961,7 @@ static int ea_set_simple(struct gfs2_inode *ip, struct buffer_head *bh,
|
||||||
static int ea_set_block(struct gfs2_inode *ip, struct gfs2_ea_request *er,
|
static int ea_set_block(struct gfs2_inode *ip, struct gfs2_ea_request *er,
|
||||||
void *private)
|
void *private)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
||||||
struct buffer_head *indbh, *newbh;
|
struct buffer_head *indbh, *newbh;
|
||||||
uint64_t *eablk;
|
uint64_t *eablk;
|
||||||
int error;
|
int error;
|
||||||
|
@ -1050,8 +1050,8 @@ static int ea_set_i(struct gfs2_inode *ip, struct gfs2_ea_request *er,
|
||||||
|
|
||||||
if (!(ip->i_di.di_flags & GFS2_DIF_EA_INDIRECT))
|
if (!(ip->i_di.di_flags & GFS2_DIF_EA_INDIRECT))
|
||||||
blks++;
|
blks++;
|
||||||
if (GFS2_EAREQ_SIZE_STUFFED(er) > ip->i_sbd->sd_jbsize)
|
if (GFS2_EAREQ_SIZE_STUFFED(er) > GFS2_SB(&ip->i_inode)->sd_jbsize)
|
||||||
blks += DIV_ROUND_UP(er->er_data_len, ip->i_sbd->sd_jbsize);
|
blks += DIV_ROUND_UP(er->er_data_len, GFS2_SB(&ip->i_inode)->sd_jbsize);
|
||||||
|
|
||||||
return ea_alloc_skeleton(ip, er, blks, ea_set_block, el);
|
return ea_alloc_skeleton(ip, er, blks, ea_set_block, el);
|
||||||
}
|
}
|
||||||
|
@ -1061,7 +1061,7 @@ static int ea_set_remove_unstuffed(struct gfs2_inode *ip,
|
||||||
{
|
{
|
||||||
if (el->el_prev && GFS2_EA2NEXT(el->el_prev) != el->el_ea) {
|
if (el->el_prev && GFS2_EA2NEXT(el->el_prev) != el->el_ea) {
|
||||||
el->el_prev = GFS2_EA2NEXT(el->el_prev);
|
el->el_prev = GFS2_EA2NEXT(el->el_prev);
|
||||||
gfs2_assert_withdraw(ip->i_sbd,
|
gfs2_assert_withdraw(GFS2_SB(&ip->i_inode),
|
||||||
GFS2_EA2NEXT(el->el_prev) == el->el_ea);
|
GFS2_EA2NEXT(el->el_prev) == el->el_ea);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1119,7 +1119,7 @@ int gfs2_ea_set(struct gfs2_inode *ip, struct gfs2_ea_request *er)
|
||||||
er->er_data = NULL;
|
er->er_data = NULL;
|
||||||
er->er_data_len = 0;
|
er->er_data_len = 0;
|
||||||
}
|
}
|
||||||
error = ea_check_size(ip->i_sbd, er);
|
error = ea_check_size(GFS2_SB(&ip->i_inode), er);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
|
@ -1127,7 +1127,7 @@ int gfs2_ea_set(struct gfs2_inode *ip, struct gfs2_ea_request *er)
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
if (IS_IMMUTABLE(ip->i_vnode))
|
if (IS_IMMUTABLE(&ip->i_inode))
|
||||||
error = -EPERM;
|
error = -EPERM;
|
||||||
else
|
else
|
||||||
error = gfs2_ea_ops[er->er_type]->eo_set(ip, er);
|
error = gfs2_ea_ops[er->er_type]->eo_set(ip, er);
|
||||||
|
@ -1144,7 +1144,7 @@ static int ea_remove_stuffed(struct gfs2_inode *ip, struct gfs2_ea_location *el)
|
||||||
struct buffer_head *dibh;
|
struct buffer_head *dibh;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
error = gfs2_trans_begin(ip->i_sbd, RES_DINODE + RES_EATTR, 0);
|
error = gfs2_trans_begin(GFS2_SB(&ip->i_inode), RES_DINODE + RES_EATTR, 0);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
|
@ -1169,7 +1169,7 @@ static int ea_remove_stuffed(struct gfs2_inode *ip, struct gfs2_ea_location *el)
|
||||||
brelse(dibh);
|
brelse(dibh);
|
||||||
}
|
}
|
||||||
|
|
||||||
gfs2_trans_end(ip->i_sbd);
|
gfs2_trans_end(GFS2_SB(&ip->i_inode));
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
@ -1219,7 +1219,7 @@ int gfs2_ea_remove(struct gfs2_inode *ip, struct gfs2_ea_request *er)
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
if (IS_IMMUTABLE(ip->i_vnode) || IS_APPEND(ip->i_vnode))
|
if (IS_IMMUTABLE(&ip->i_inode) || IS_APPEND(&ip->i_inode))
|
||||||
error = -EPERM;
|
error = -EPERM;
|
||||||
else
|
else
|
||||||
error = gfs2_ea_ops[er->er_type]->eo_remove(ip, er);
|
error = gfs2_ea_ops[er->er_type]->eo_remove(ip, er);
|
||||||
|
@ -1232,7 +1232,7 @@ int gfs2_ea_remove(struct gfs2_inode *ip, struct gfs2_ea_request *er)
|
||||||
static int ea_acl_chmod_unstuffed(struct gfs2_inode *ip,
|
static int ea_acl_chmod_unstuffed(struct gfs2_inode *ip,
|
||||||
struct gfs2_ea_header *ea, char *data)
|
struct gfs2_ea_header *ea, char *data)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
||||||
struct buffer_head **bh;
|
struct buffer_head **bh;
|
||||||
unsigned int amount = GFS2_EA_DATA_LEN(ea);
|
unsigned int amount = GFS2_EA_DATA_LEN(ea);
|
||||||
unsigned int nptrs = DIV_ROUND_UP(amount, sdp->sd_jbsize);
|
unsigned int nptrs = DIV_ROUND_UP(amount, sdp->sd_jbsize);
|
||||||
|
@ -1304,7 +1304,7 @@ int gfs2_ea_acl_chmod(struct gfs2_inode *ip, struct gfs2_ea_location *el,
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
if (GFS2_EA_IS_STUFFED(el->el_ea)) {
|
if (GFS2_EA_IS_STUFFED(el->el_ea)) {
|
||||||
error = gfs2_trans_begin(ip->i_sbd, RES_DINODE + RES_EATTR, 0);
|
error = gfs2_trans_begin(GFS2_SB(&ip->i_inode), RES_DINODE + RES_EATTR, 0);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
|
@ -1320,22 +1320,22 @@ int gfs2_ea_acl_chmod(struct gfs2_inode *ip, struct gfs2_ea_location *el,
|
||||||
|
|
||||||
error = gfs2_meta_inode_buffer(ip, &dibh);
|
error = gfs2_meta_inode_buffer(ip, &dibh);
|
||||||
if (!error) {
|
if (!error) {
|
||||||
error = inode_setattr(ip->i_vnode, attr);
|
error = inode_setattr(&ip->i_inode, attr);
|
||||||
gfs2_assert_warn(ip->i_sbd, !error);
|
gfs2_assert_warn(GFS2_SB(&ip->i_inode), !error);
|
||||||
gfs2_inode_attr_out(ip);
|
gfs2_inode_attr_out(ip);
|
||||||
gfs2_trans_add_bh(ip->i_gl, dibh, 1);
|
gfs2_trans_add_bh(ip->i_gl, dibh, 1);
|
||||||
gfs2_dinode_out(&ip->i_di, dibh->b_data);
|
gfs2_dinode_out(&ip->i_di, dibh->b_data);
|
||||||
brelse(dibh);
|
brelse(dibh);
|
||||||
}
|
}
|
||||||
|
|
||||||
gfs2_trans_end(ip->i_sbd);
|
gfs2_trans_end(GFS2_SB(&ip->i_inode));
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ea_dealloc_indirect(struct gfs2_inode *ip)
|
static int ea_dealloc_indirect(struct gfs2_inode *ip)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
||||||
struct gfs2_rgrp_list rlist;
|
struct gfs2_rgrp_list rlist;
|
||||||
struct buffer_head *indbh, *dibh;
|
struct buffer_head *indbh, *dibh;
|
||||||
uint64_t *eablk, *end;
|
uint64_t *eablk, *end;
|
||||||
|
@ -1456,7 +1456,7 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip)
|
||||||
|
|
||||||
static int ea_dealloc_block(struct gfs2_inode *ip)
|
static int ea_dealloc_block(struct gfs2_inode *ip)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
||||||
struct gfs2_alloc *al = &ip->i_alloc;
|
struct gfs2_alloc *al = &ip->i_alloc;
|
||||||
struct gfs2_rgrpd *rgd;
|
struct gfs2_rgrpd *rgd;
|
||||||
struct buffer_head *dibh;
|
struct buffer_head *dibh;
|
||||||
|
@ -1518,7 +1518,7 @@ int gfs2_ea_dealloc(struct gfs2_inode *ip)
|
||||||
if (error)
|
if (error)
|
||||||
goto out_alloc;
|
goto out_alloc;
|
||||||
|
|
||||||
error = gfs2_rindex_hold(ip->i_sbd, &al->al_ri_gh);
|
error = gfs2_rindex_hold(GFS2_SB(&ip->i_inode), &al->al_ri_gh);
|
||||||
if (error)
|
if (error)
|
||||||
goto out_quota;
|
goto out_quota;
|
||||||
|
|
||||||
|
|
102
fs/gfs2/glock.c
102
fs/gfs2/glock.c
|
@ -654,7 +654,7 @@ static void run_queue(struct gfs2_glock *gl)
|
||||||
* Gives caller exclusive access to manipulate a glock structure.
|
* Gives caller exclusive access to manipulate a glock structure.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void gfs2_glmutex_lock(struct gfs2_glock *gl)
|
static void gfs2_glmutex_lock(struct gfs2_glock *gl)
|
||||||
{
|
{
|
||||||
struct gfs2_holder gh;
|
struct gfs2_holder gh;
|
||||||
|
|
||||||
|
@ -704,7 +704,7 @@ static int gfs2_glmutex_trylock(struct gfs2_glock *gl)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void gfs2_glmutex_unlock(struct gfs2_glock *gl)
|
static void gfs2_glmutex_unlock(struct gfs2_glock *gl)
|
||||||
{
|
{
|
||||||
spin_lock(&gl->gl_spin);
|
spin_lock(&gl->gl_spin);
|
||||||
clear_bit(GLF_LOCK, &gl->gl_flags);
|
clear_bit(GLF_LOCK, &gl->gl_flags);
|
||||||
|
@ -726,7 +726,7 @@ static void handle_callback(struct gfs2_glock *gl, unsigned int state)
|
||||||
{
|
{
|
||||||
struct gfs2_holder *gh, *new_gh = NULL;
|
struct gfs2_holder *gh, *new_gh = NULL;
|
||||||
|
|
||||||
restart:
|
restart:
|
||||||
spin_lock(&gl->gl_spin);
|
spin_lock(&gl->gl_spin);
|
||||||
|
|
||||||
list_for_each_entry(gh, &gl->gl_waiters2, gh_list) {
|
list_for_each_entry(gh, &gl->gl_waiters2, gh_list) {
|
||||||
|
@ -752,13 +752,27 @@ static void handle_callback(struct gfs2_glock *gl, unsigned int state)
|
||||||
goto restart;
|
goto restart;
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
spin_unlock(&gl->gl_spin);
|
spin_unlock(&gl->gl_spin);
|
||||||
|
|
||||||
if (new_gh)
|
if (new_gh)
|
||||||
gfs2_holder_put(new_gh);
|
gfs2_holder_put(new_gh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gfs2_glock_inode_squish(struct inode *inode)
|
||||||
|
{
|
||||||
|
struct gfs2_holder gh;
|
||||||
|
struct gfs2_glock *gl = GFS2_I(inode)->i_gl;
|
||||||
|
gfs2_holder_init(gl, LM_ST_UNLOCKED, 0, &gh);
|
||||||
|
set_bit(HIF_DEMOTE, &gh.gh_iflags);
|
||||||
|
spin_lock(&gl->gl_spin);
|
||||||
|
gfs2_assert(inode->i_sb->s_fs_info, list_empty(&gl->gl_holders));
|
||||||
|
list_add_tail(&gh.gh_list, &gl->gl_waiters2);
|
||||||
|
run_queue(gl);
|
||||||
|
spin_unlock(&gl->gl_spin);
|
||||||
|
gfs2_holder_uninit(&gh);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* state_change - record that the glock is now in a different state
|
* state_change - record that the glock is now in a different state
|
||||||
* @gl: the glock
|
* @gl: the glock
|
||||||
|
@ -1383,8 +1397,7 @@ int gfs2_glock_be_greedy(struct gfs2_glock *gl, unsigned int time)
|
||||||
struct greedy *gr;
|
struct greedy *gr;
|
||||||
struct gfs2_holder *gh;
|
struct gfs2_holder *gh;
|
||||||
|
|
||||||
if (!time ||
|
if (!time || gl->gl_sbd->sd_args.ar_localcaching ||
|
||||||
gl->gl_sbd->sd_args.ar_localcaching ||
|
|
||||||
test_and_set_bit(GLF_GREEDY, &gl->gl_flags))
|
test_and_set_bit(GLF_GREEDY, &gl->gl_flags))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
@ -1784,43 +1797,6 @@ void gfs2_glock_cb(lm_fsdata_t *fsdata, unsigned int type, void *data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* gfs2_try_toss_inode - try to remove a particular inode struct from cache
|
|
||||||
* sdp: the filesystem
|
|
||||||
* inum: the inode number
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
void gfs2_try_toss_inode(struct gfs2_sbd *sdp, struct gfs2_inum *inum)
|
|
||||||
{
|
|
||||||
struct gfs2_glock *gl;
|
|
||||||
struct gfs2_inode *ip;
|
|
||||||
int error;
|
|
||||||
|
|
||||||
error = gfs2_glock_get(sdp, inum->no_addr, &gfs2_inode_glops,
|
|
||||||
NO_CREATE, &gl);
|
|
||||||
if (error || !gl)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!gfs2_glmutex_trylock(gl))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
ip = gl->gl_object;
|
|
||||||
if (!ip)
|
|
||||||
goto out_unlock;
|
|
||||||
|
|
||||||
if (atomic_read(&ip->i_count))
|
|
||||||
goto out_unlock;
|
|
||||||
|
|
||||||
gfs2_inode_destroy(ip, 1);
|
|
||||||
|
|
||||||
out_unlock:
|
|
||||||
gfs2_glmutex_unlock(gl);
|
|
||||||
|
|
||||||
out:
|
|
||||||
gfs2_glock_put(gl);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gfs2_iopen_go_callback - Try to kick the inode/vnode associated with an
|
* gfs2_iopen_go_callback - Try to kick the inode/vnode associated with an
|
||||||
* iopen glock from memory
|
* iopen glock from memory
|
||||||
|
@ -1831,34 +1807,10 @@ void gfs2_try_toss_inode(struct gfs2_sbd *sdp, struct gfs2_inum *inum)
|
||||||
|
|
||||||
void gfs2_iopen_go_callback(struct gfs2_glock *io_gl, unsigned int state)
|
void gfs2_iopen_go_callback(struct gfs2_glock *io_gl, unsigned int state)
|
||||||
{
|
{
|
||||||
struct gfs2_glock *i_gl;
|
|
||||||
|
|
||||||
if (state != LM_ST_UNLOCKED)
|
if (state != LM_ST_UNLOCKED)
|
||||||
return;
|
return;
|
||||||
|
/* FIXME: remove this? */
|
||||||
spin_lock(&io_gl->gl_spin);
|
|
||||||
i_gl = io_gl->gl_object;
|
|
||||||
if (i_gl) {
|
|
||||||
gfs2_glock_hold(i_gl);
|
|
||||||
spin_unlock(&io_gl->gl_spin);
|
|
||||||
} else {
|
|
||||||
spin_unlock(&io_gl->gl_spin);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gfs2_glmutex_trylock(i_gl)) {
|
|
||||||
struct gfs2_inode *ip = i_gl->gl_object;
|
|
||||||
if (ip) {
|
|
||||||
gfs2_try_toss_vnode(ip);
|
|
||||||
gfs2_glmutex_unlock(i_gl);
|
|
||||||
gfs2_glock_schedule_for_reclaim(i_gl);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
gfs2_glmutex_unlock(i_gl);
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
gfs2_glock_put(i_gl);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1935,11 +1887,6 @@ void gfs2_reclaim_glock(struct gfs2_sbd *sdp)
|
||||||
atomic_inc(&sdp->sd_reclaimed);
|
atomic_inc(&sdp->sd_reclaimed);
|
||||||
|
|
||||||
if (gfs2_glmutex_trylock(gl)) {
|
if (gfs2_glmutex_trylock(gl)) {
|
||||||
if (gl->gl_ops == &gfs2_inode_glops) {
|
|
||||||
struct gfs2_inode *ip = gl->gl_object;
|
|
||||||
if (ip && !atomic_read(&ip->i_count))
|
|
||||||
gfs2_inode_destroy(ip, 1);
|
|
||||||
}
|
|
||||||
if (queue_empty(gl, &gl->gl_holders) &&
|
if (queue_empty(gl, &gl->gl_holders) &&
|
||||||
gl->gl_state != LM_ST_UNLOCKED &&
|
gl->gl_state != LM_ST_UNLOCKED &&
|
||||||
demote_ok(gl))
|
demote_ok(gl))
|
||||||
|
@ -2018,7 +1965,7 @@ static void scan_glock(struct gfs2_glock *gl)
|
||||||
if (gfs2_glmutex_trylock(gl)) {
|
if (gfs2_glmutex_trylock(gl)) {
|
||||||
if (gl->gl_ops == &gfs2_inode_glops) {
|
if (gl->gl_ops == &gfs2_inode_glops) {
|
||||||
struct gfs2_inode *ip = gl->gl_object;
|
struct gfs2_inode *ip = gl->gl_object;
|
||||||
if (ip && !atomic_read(&ip->i_count))
|
if (ip)
|
||||||
goto out_schedule;
|
goto out_schedule;
|
||||||
}
|
}
|
||||||
if (queue_empty(gl, &gl->gl_holders) &&
|
if (queue_empty(gl, &gl->gl_holders) &&
|
||||||
|
@ -2078,11 +2025,6 @@ static void clear_glock(struct gfs2_glock *gl)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gfs2_glmutex_trylock(gl)) {
|
if (gfs2_glmutex_trylock(gl)) {
|
||||||
if (gl->gl_ops == &gfs2_inode_glops) {
|
|
||||||
struct gfs2_inode *ip = gl->gl_object;
|
|
||||||
if (ip && !atomic_read(&ip->i_count))
|
|
||||||
gfs2_inode_destroy(ip, 1);
|
|
||||||
}
|
|
||||||
if (queue_empty(gl, &gl->gl_holders) &&
|
if (queue_empty(gl, &gl->gl_holders) &&
|
||||||
gl->gl_state != LM_ST_UNLOCKED)
|
gl->gl_state != LM_ST_UNLOCKED)
|
||||||
handle_callback(gl, LM_ST_UNLOCKED);
|
handle_callback(gl, LM_ST_UNLOCKED);
|
||||||
|
@ -2199,13 +2141,11 @@ static int dump_inode(struct gfs2_inode *ip)
|
||||||
(unsigned long long)ip->i_num.no_formal_ino,
|
(unsigned long long)ip->i_num.no_formal_ino,
|
||||||
(unsigned long long)ip->i_num.no_addr);
|
(unsigned long long)ip->i_num.no_addr);
|
||||||
printk(KERN_INFO " type = %u\n", IF2DT(ip->i_di.di_mode));
|
printk(KERN_INFO " type = %u\n", IF2DT(ip->i_di.di_mode));
|
||||||
printk(KERN_INFO " i_count = %d\n", atomic_read(&ip->i_count));
|
|
||||||
printk(KERN_INFO " i_flags =");
|
printk(KERN_INFO " i_flags =");
|
||||||
for (x = 0; x < 32; x++)
|
for (x = 0; x < 32; x++)
|
||||||
if (test_bit(x, &ip->i_flags))
|
if (test_bit(x, &ip->i_flags))
|
||||||
printk(" %u", x);
|
printk(" %u", x);
|
||||||
printk(" \n");
|
printk(" \n");
|
||||||
printk(KERN_INFO " vnode = %s\n", (ip->i_vnode) ? "yes" : "no");
|
|
||||||
|
|
||||||
error = 0;
|
error = 0;
|
||||||
|
|
||||||
|
|
|
@ -88,9 +88,6 @@ void gfs2_holder_uninit(struct gfs2_holder *gh);
|
||||||
void gfs2_glock_xmote_th(struct gfs2_glock *gl, unsigned int state, int flags);
|
void gfs2_glock_xmote_th(struct gfs2_glock *gl, unsigned int state, int flags);
|
||||||
void gfs2_glock_drop_th(struct gfs2_glock *gl);
|
void gfs2_glock_drop_th(struct gfs2_glock *gl);
|
||||||
|
|
||||||
void gfs2_glmutex_lock(struct gfs2_glock *gl);
|
|
||||||
void gfs2_glmutex_unlock(struct gfs2_glock *gl);
|
|
||||||
|
|
||||||
int gfs2_glock_nq(struct gfs2_holder *gh);
|
int gfs2_glock_nq(struct gfs2_holder *gh);
|
||||||
int gfs2_glock_poll(struct gfs2_holder *gh);
|
int gfs2_glock_poll(struct gfs2_holder *gh);
|
||||||
int gfs2_glock_wait(struct gfs2_holder *gh);
|
int gfs2_glock_wait(struct gfs2_holder *gh);
|
||||||
|
@ -110,6 +107,7 @@ void gfs2_glock_dq_uninit_m(unsigned int num_gh, struct gfs2_holder *ghs);
|
||||||
void gfs2_glock_prefetch_num(struct gfs2_sbd *sdp, uint64_t number,
|
void gfs2_glock_prefetch_num(struct gfs2_sbd *sdp, uint64_t number,
|
||||||
struct gfs2_glock_operations *glops,
|
struct gfs2_glock_operations *glops,
|
||||||
unsigned int state, int flags);
|
unsigned int state, int flags);
|
||||||
|
void gfs2_glock_inode_squish(struct inode *inode);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gfs2_glock_nq_init - intialize a holder and enqueue it on a glock
|
* gfs2_glock_nq_init - intialize a holder and enqueue it on a glock
|
||||||
|
@ -143,7 +141,6 @@ void gfs2_lvb_unhold(struct gfs2_glock *gl);
|
||||||
|
|
||||||
void gfs2_glock_cb(lm_fsdata_t *fsdata, unsigned int type, void *data);
|
void gfs2_glock_cb(lm_fsdata_t *fsdata, unsigned int type, void *data);
|
||||||
|
|
||||||
void gfs2_try_toss_inode(struct gfs2_sbd *sdp, struct gfs2_inum *inum);
|
|
||||||
void gfs2_iopen_go_callback(struct gfs2_glock *gl, unsigned int state);
|
void gfs2_iopen_go_callback(struct gfs2_glock *gl, unsigned int state);
|
||||||
|
|
||||||
void gfs2_glock_schedule_for_reclaim(struct gfs2_glock *gl);
|
void gfs2_glock_schedule_for_reclaim(struct gfs2_glock *gl);
|
||||||
|
|
|
@ -129,6 +129,7 @@ static void inode_go_xmote_bh(struct gfs2_glock *gl)
|
||||||
|
|
||||||
static void inode_go_drop_th(struct gfs2_glock *gl)
|
static void inode_go_drop_th(struct gfs2_glock *gl)
|
||||||
{
|
{
|
||||||
|
printk(KERN_INFO "drop th %p\n", gl->gl_object);
|
||||||
gfs2_pte_inval(gl);
|
gfs2_pte_inval(gl);
|
||||||
gfs2_glock_drop_th(gl);
|
gfs2_glock_drop_th(gl);
|
||||||
}
|
}
|
||||||
|
@ -147,6 +148,7 @@ static void inode_go_sync(struct gfs2_glock *gl, int flags)
|
||||||
|
|
||||||
if (test_bit(GLF_DIRTY, &gl->gl_flags)) {
|
if (test_bit(GLF_DIRTY, &gl->gl_flags)) {
|
||||||
if (meta && data) {
|
if (meta && data) {
|
||||||
|
printk(KERN_INFO "sync all\n");
|
||||||
gfs2_page_sync(gl, flags | DIO_START);
|
gfs2_page_sync(gl, flags | DIO_START);
|
||||||
gfs2_log_flush(gl->gl_sbd, gl);
|
gfs2_log_flush(gl->gl_sbd, gl);
|
||||||
gfs2_meta_sync(gl, flags | DIO_START | DIO_WAIT);
|
gfs2_meta_sync(gl, flags | DIO_START | DIO_WAIT);
|
||||||
|
@ -224,6 +226,7 @@ static int inode_go_lock(struct gfs2_holder *gh)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (ip->i_vn != gl->gl_vn) {
|
if (ip->i_vn != gl->gl_vn) {
|
||||||
|
printk(KERN_INFO "refresh inode %p\n", &ip->i_inode);
|
||||||
error = gfs2_inode_refresh(ip);
|
error = gfs2_inode_refresh(ip);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
@ -288,7 +291,7 @@ static void inode_greedy(struct gfs2_glock *gl)
|
||||||
|
|
||||||
spin_unlock(&ip->i_spin);
|
spin_unlock(&ip->i_spin);
|
||||||
|
|
||||||
gfs2_inode_put(ip);
|
iput(&ip->i_inode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -361,14 +364,14 @@ static void trans_go_xmote_th(struct gfs2_glock *gl, unsigned int state,
|
||||||
static void trans_go_xmote_bh(struct gfs2_glock *gl)
|
static void trans_go_xmote_bh(struct gfs2_glock *gl)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = gl->gl_sbd;
|
struct gfs2_sbd *sdp = gl->gl_sbd;
|
||||||
struct gfs2_inode *ip = sdp->sd_jdesc->jd_inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(sdp->sd_jdesc->jd_inode);
|
||||||
struct gfs2_glock *j_gl = ip->i_gl;
|
struct gfs2_glock *j_gl = ip->i_gl;
|
||||||
struct gfs2_log_header head;
|
struct gfs2_log_header head;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
if (gl->gl_state != LM_ST_UNLOCKED &&
|
if (gl->gl_state != LM_ST_UNLOCKED &&
|
||||||
test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) {
|
test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) {
|
||||||
gfs2_meta_cache_flush(sdp->sd_jdesc->jd_inode->u.generic_ip);
|
gfs2_meta_cache_flush(GFS2_I(sdp->sd_jdesc->jd_inode));
|
||||||
j_gl->gl_ops->go_inval(j_gl, DIO_METADATA | DIO_DATA);
|
j_gl->gl_ops->go_inval(j_gl, DIO_METADATA | DIO_DATA);
|
||||||
|
|
||||||
error = gfs2_find_jhead(sdp->sd_jdesc, &head);
|
error = gfs2_find_jhead(sdp->sd_jdesc, &head);
|
||||||
|
|
|
@ -33,7 +33,6 @@ struct gfs2_inode;
|
||||||
struct gfs2_file;
|
struct gfs2_file;
|
||||||
struct gfs2_revoke;
|
struct gfs2_revoke;
|
||||||
struct gfs2_revoke_replay;
|
struct gfs2_revoke_replay;
|
||||||
struct gfs2_unlinked;
|
|
||||||
struct gfs2_quota_data;
|
struct gfs2_quota_data;
|
||||||
struct gfs2_log_buf;
|
struct gfs2_log_buf;
|
||||||
struct gfs2_trans;
|
struct gfs2_trans;
|
||||||
|
@ -245,16 +244,12 @@ struct gfs2_inode {
|
||||||
struct inode i_inode;
|
struct inode i_inode;
|
||||||
struct gfs2_inum i_num;
|
struct gfs2_inum i_num;
|
||||||
|
|
||||||
atomic_t i_count;
|
|
||||||
unsigned long i_flags; /* GIF_... */
|
unsigned long i_flags; /* GIF_... */
|
||||||
|
|
||||||
uint64_t i_vn;
|
uint64_t i_vn;
|
||||||
struct gfs2_dinode i_di;
|
struct gfs2_dinode i_di; /* To be replaced by ref to block */
|
||||||
|
|
||||||
struct gfs2_glock *i_gl;
|
|
||||||
struct gfs2_sbd *i_sbd;
|
|
||||||
struct inode *i_vnode;
|
|
||||||
|
|
||||||
|
struct gfs2_glock *i_gl; /* Move into i_gh? */
|
||||||
struct gfs2_holder i_iopen_gh;
|
struct gfs2_holder i_iopen_gh;
|
||||||
struct gfs2_holder i_gh; /* for prepare/commit_write only */
|
struct gfs2_holder i_gh; /* for prepare/commit_write only */
|
||||||
struct gfs2_alloc i_alloc;
|
struct gfs2_alloc i_alloc;
|
||||||
|
@ -262,18 +257,27 @@ struct gfs2_inode {
|
||||||
|
|
||||||
spinlock_t i_spin;
|
spinlock_t i_spin;
|
||||||
struct rw_semaphore i_rw_mutex;
|
struct rw_semaphore i_rw_mutex;
|
||||||
|
|
||||||
unsigned int i_greedy;
|
unsigned int i_greedy;
|
||||||
unsigned long i_last_pfault;
|
unsigned long i_last_pfault;
|
||||||
|
|
||||||
struct buffer_head *i_cache[GFS2_MAX_META_HEIGHT];
|
struct buffer_head *i_cache[GFS2_MAX_META_HEIGHT];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Since i_inode is the first element of struct gfs2_inode,
|
||||||
|
* this is effectively a cast.
|
||||||
|
*/
|
||||||
static inline struct gfs2_inode *GFS2_I(struct inode *inode)
|
static inline struct gfs2_inode *GFS2_I(struct inode *inode)
|
||||||
{
|
{
|
||||||
return container_of(inode, struct gfs2_inode, i_inode);
|
return container_of(inode, struct gfs2_inode, i_inode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* To be removed? */
|
||||||
|
static inline struct gfs2_sbd *GFS2_SB(struct inode *inode)
|
||||||
|
{
|
||||||
|
return inode->i_sb->s_fs_info;
|
||||||
|
}
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
GFF_DID_DIRECT_ALLOC = 0,
|
GFF_DID_DIRECT_ALLOC = 0,
|
||||||
};
|
};
|
||||||
|
@ -295,18 +299,6 @@ struct gfs2_revoke_replay {
|
||||||
unsigned int rr_where;
|
unsigned int rr_where;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
|
||||||
ULF_LOCKED = 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct gfs2_unlinked {
|
|
||||||
struct list_head ul_list;
|
|
||||||
unsigned int ul_count;
|
|
||||||
struct gfs2_unlinked_tag ul_ut;
|
|
||||||
unsigned long ul_flags; /* ULF_... */
|
|
||||||
unsigned int ul_slot;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
QDF_USER = 0,
|
QDF_USER = 0,
|
||||||
QDF_CHANGE = 1,
|
QDF_CHANGE = 1,
|
||||||
|
@ -436,7 +428,6 @@ struct gfs2_tune {
|
||||||
unsigned int gt_recoverd_secs;
|
unsigned int gt_recoverd_secs;
|
||||||
unsigned int gt_logd_secs;
|
unsigned int gt_logd_secs;
|
||||||
unsigned int gt_quotad_secs;
|
unsigned int gt_quotad_secs;
|
||||||
unsigned int gt_inoded_secs;
|
|
||||||
|
|
||||||
unsigned int gt_quota_simul_sync; /* Max quotavals to sync at once */
|
unsigned int gt_quota_simul_sync; /* Max quotavals to sync at once */
|
||||||
unsigned int gt_quota_warn_period; /* Secs between quota warn msgs */
|
unsigned int gt_quota_warn_period; /* Secs between quota warn msgs */
|
||||||
|
@ -495,7 +486,6 @@ struct gfs2_sbd {
|
||||||
uint32_t sd_hash_bsize; /* sizeof(exhash block) */
|
uint32_t sd_hash_bsize; /* sizeof(exhash block) */
|
||||||
uint32_t sd_hash_bsize_shift;
|
uint32_t sd_hash_bsize_shift;
|
||||||
uint32_t sd_hash_ptrs; /* Number of pointers in a hash block */
|
uint32_t sd_hash_ptrs; /* Number of pointers in a hash block */
|
||||||
uint32_t sd_ut_per_block;
|
|
||||||
uint32_t sd_qc_per_block;
|
uint32_t sd_qc_per_block;
|
||||||
uint32_t sd_max_dirres; /* Max blocks needed to add a directory entry */
|
uint32_t sd_max_dirres; /* Max blocks needed to add a directory entry */
|
||||||
uint32_t sd_max_height; /* Max height of a file's metadata tree */
|
uint32_t sd_max_height; /* Max height of a file's metadata tree */
|
||||||
|
@ -527,7 +517,6 @@ struct gfs2_sbd {
|
||||||
struct inode *sd_statfs_inode;
|
struct inode *sd_statfs_inode;
|
||||||
struct inode *sd_ir_inode;
|
struct inode *sd_ir_inode;
|
||||||
struct inode *sd_sc_inode;
|
struct inode *sd_sc_inode;
|
||||||
struct inode *sd_ut_inode;
|
|
||||||
struct inode *sd_qc_inode;
|
struct inode *sd_qc_inode;
|
||||||
struct inode *sd_rindex;
|
struct inode *sd_rindex;
|
||||||
struct inode *sd_quota_inode;
|
struct inode *sd_quota_inode;
|
||||||
|
@ -569,7 +558,6 @@ struct gfs2_sbd {
|
||||||
|
|
||||||
struct gfs2_holder sd_ir_gh;
|
struct gfs2_holder sd_ir_gh;
|
||||||
struct gfs2_holder sd_sc_gh;
|
struct gfs2_holder sd_sc_gh;
|
||||||
struct gfs2_holder sd_ut_gh;
|
|
||||||
struct gfs2_holder sd_qc_gh;
|
struct gfs2_holder sd_qc_gh;
|
||||||
|
|
||||||
/* Daemon stuff */
|
/* Daemon stuff */
|
||||||
|
@ -578,21 +566,9 @@ struct gfs2_sbd {
|
||||||
struct task_struct *sd_recoverd_process;
|
struct task_struct *sd_recoverd_process;
|
||||||
struct task_struct *sd_logd_process;
|
struct task_struct *sd_logd_process;
|
||||||
struct task_struct *sd_quotad_process;
|
struct task_struct *sd_quotad_process;
|
||||||
struct task_struct *sd_inoded_process;
|
|
||||||
struct task_struct *sd_glockd_process[GFS2_GLOCKD_MAX];
|
struct task_struct *sd_glockd_process[GFS2_GLOCKD_MAX];
|
||||||
unsigned int sd_glockd_num;
|
unsigned int sd_glockd_num;
|
||||||
|
|
||||||
/* Unlinked inode stuff */
|
|
||||||
|
|
||||||
struct list_head sd_unlinked_list;
|
|
||||||
atomic_t sd_unlinked_count;
|
|
||||||
spinlock_t sd_unlinked_spin;
|
|
||||||
struct mutex sd_unlinked_mutex;
|
|
||||||
|
|
||||||
unsigned int sd_unlinked_slots;
|
|
||||||
unsigned int sd_unlinked_chunks;
|
|
||||||
unsigned char **sd_unlinked_bitmap;
|
|
||||||
|
|
||||||
/* Quota stuff */
|
/* Quota stuff */
|
||||||
|
|
||||||
struct list_head sd_quota_list;
|
struct list_head sd_quota_list;
|
||||||
|
|
817
fs/gfs2/inode.c
817
fs/gfs2/inode.c
File diff suppressed because it is too large
Load Diff
|
@ -27,32 +27,20 @@ static inline int gfs2_is_dir(struct gfs2_inode *ip)
|
||||||
|
|
||||||
void gfs2_inode_attr_in(struct gfs2_inode *ip);
|
void gfs2_inode_attr_in(struct gfs2_inode *ip);
|
||||||
void gfs2_inode_attr_out(struct gfs2_inode *ip);
|
void gfs2_inode_attr_out(struct gfs2_inode *ip);
|
||||||
struct inode *gfs2_ip2v_lookup(struct gfs2_inode *ip);
|
struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum *inum, unsigned type);
|
||||||
struct inode *gfs2_ip2v(struct gfs2_inode *ip);
|
struct inode *gfs2_ilookup(struct super_block *sb, struct gfs2_inum *inum);
|
||||||
struct inode *gfs2_iget(struct super_block *sb, struct gfs2_inum *inum);
|
|
||||||
|
|
||||||
void gfs2_inode_min_init(struct gfs2_inode *ip, unsigned int type);
|
|
||||||
int gfs2_inode_refresh(struct gfs2_inode *ip);
|
int gfs2_inode_refresh(struct gfs2_inode *ip);
|
||||||
|
|
||||||
int gfs2_inode_get(struct gfs2_glock *i_gl,
|
int gfs2_dinode_dealloc(struct gfs2_inode *inode);
|
||||||
const struct gfs2_inum *inum, int create,
|
|
||||||
struct gfs2_inode **ipp);
|
|
||||||
void gfs2_inode_hold(struct gfs2_inode *ip);
|
|
||||||
void gfs2_inode_put(struct gfs2_inode *ip);
|
|
||||||
void gfs2_inode_destroy(struct gfs2_inode *ip, int unlock);
|
|
||||||
|
|
||||||
int gfs2_inode_dealloc(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul);
|
|
||||||
|
|
||||||
int gfs2_change_nlink(struct gfs2_inode *ip, int diff);
|
int gfs2_change_nlink(struct gfs2_inode *ip, int diff);
|
||||||
struct inode *gfs2_lookupi(struct inode *dir, struct qstr *name, int is_root,
|
struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name,
|
||||||
struct nameidata *nd);
|
int is_root, struct nameidata *nd);
|
||||||
struct inode *gfs2_createi(struct gfs2_holder *ghs, struct qstr *name,
|
struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name,
|
||||||
unsigned int mode);
|
unsigned int mode);
|
||||||
int gfs2_unlinki(struct gfs2_inode *dip, struct qstr *name,
|
int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name,
|
||||||
struct gfs2_inode *ip, struct gfs2_unlinked *ul);
|
struct gfs2_inode *ip);
|
||||||
int gfs2_rmdiri(struct gfs2_inode *dip, struct qstr *name,
|
int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name,
|
||||||
struct gfs2_inode *ip, struct gfs2_unlinked *ul);
|
|
||||||
int gfs2_unlink_ok(struct gfs2_inode *dip, struct qstr *name,
|
|
||||||
struct gfs2_inode *ip);
|
struct gfs2_inode *ip);
|
||||||
int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to);
|
int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to);
|
||||||
int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len);
|
int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len);
|
||||||
|
@ -60,8 +48,6 @@ int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len);
|
||||||
int gfs2_glock_nq_atime(struct gfs2_holder *gh);
|
int gfs2_glock_nq_atime(struct gfs2_holder *gh);
|
||||||
int gfs2_glock_nq_m_atime(unsigned int num_gh, struct gfs2_holder *ghs);
|
int gfs2_glock_nq_m_atime(unsigned int num_gh, struct gfs2_holder *ghs);
|
||||||
|
|
||||||
void gfs2_try_toss_vnode(struct gfs2_inode *ip);
|
|
||||||
|
|
||||||
int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr);
|
int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr);
|
||||||
|
|
||||||
int gfs2_repermission(struct inode *inode, int mask, struct nameidata *nd);
|
int gfs2_repermission(struct inode *inode, int mask, struct nameidata *nd);
|
||||||
|
|
|
@ -213,6 +213,9 @@ static uint64_t log_bmap(struct gfs2_sbd *sdp, unsigned int lbn)
|
||||||
int bdy;
|
int bdy;
|
||||||
|
|
||||||
error = gfs2_block_map(sdp->sd_jdesc->jd_inode, lbn, &new, &dbn, &bdy);
|
error = gfs2_block_map(sdp->sd_jdesc->jd_inode, lbn, &new, &dbn, &bdy);
|
||||||
|
if (!(!error && dbn)) {
|
||||||
|
printk(KERN_INFO "error=%d, dbn=%llu lbn=%u", error, dbn, lbn);
|
||||||
|
}
|
||||||
gfs2_assert_withdraw(sdp, !error && dbn);
|
gfs2_assert_withdraw(sdp, !error && dbn);
|
||||||
|
|
||||||
return dbn;
|
return dbn;
|
||||||
|
|
|
@ -184,8 +184,7 @@ static void buf_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_ail *ai)
|
||||||
static void buf_lo_before_scan(struct gfs2_jdesc *jd,
|
static void buf_lo_before_scan(struct gfs2_jdesc *jd,
|
||||||
struct gfs2_log_header *head, int pass)
|
struct gfs2_log_header *head, int pass)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = jd->jd_inode->u.generic_ip;
|
struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
|
||||||
|
|
||||||
if (pass != 0)
|
if (pass != 0)
|
||||||
return;
|
return;
|
||||||
|
@ -198,8 +197,8 @@ static int buf_lo_scan_elements(struct gfs2_jdesc *jd, unsigned int start,
|
||||||
struct gfs2_log_descriptor *ld, __be64 *ptr,
|
struct gfs2_log_descriptor *ld, __be64 *ptr,
|
||||||
int pass)
|
int pass)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = jd->jd_inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
|
||||||
struct gfs2_glock *gl = ip->i_gl;
|
struct gfs2_glock *gl = ip->i_gl;
|
||||||
unsigned int blks = be32_to_cpu(ld->ld_data1);
|
unsigned int blks = be32_to_cpu(ld->ld_data1);
|
||||||
struct buffer_head *bh_log, *bh_ip;
|
struct buffer_head *bh_log, *bh_ip;
|
||||||
|
@ -245,8 +244,8 @@ static int buf_lo_scan_elements(struct gfs2_jdesc *jd, unsigned int start,
|
||||||
|
|
||||||
static void buf_lo_after_scan(struct gfs2_jdesc *jd, int error, int pass)
|
static void buf_lo_after_scan(struct gfs2_jdesc *jd, int error, int pass)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = jd->jd_inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
gfs2_meta_sync(ip->i_gl,
|
gfs2_meta_sync(ip->i_gl,
|
||||||
|
@ -332,8 +331,7 @@ static void revoke_lo_before_commit(struct gfs2_sbd *sdp)
|
||||||
static void revoke_lo_before_scan(struct gfs2_jdesc *jd,
|
static void revoke_lo_before_scan(struct gfs2_jdesc *jd,
|
||||||
struct gfs2_log_header *head, int pass)
|
struct gfs2_log_header *head, int pass)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = jd->jd_inode->u.generic_ip;
|
struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
|
||||||
|
|
||||||
if (pass != 0)
|
if (pass != 0)
|
||||||
return;
|
return;
|
||||||
|
@ -346,8 +344,7 @@ static int revoke_lo_scan_elements(struct gfs2_jdesc *jd, unsigned int start,
|
||||||
struct gfs2_log_descriptor *ld, __be64 *ptr,
|
struct gfs2_log_descriptor *ld, __be64 *ptr,
|
||||||
int pass)
|
int pass)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = jd->jd_inode->u.generic_ip;
|
struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
|
||||||
unsigned int blks = be32_to_cpu(ld->ld_length);
|
unsigned int blks = be32_to_cpu(ld->ld_length);
|
||||||
unsigned int revokes = be32_to_cpu(ld->ld_data1);
|
unsigned int revokes = be32_to_cpu(ld->ld_data1);
|
||||||
struct buffer_head *bh;
|
struct buffer_head *bh;
|
||||||
|
@ -393,8 +390,7 @@ static int revoke_lo_scan_elements(struct gfs2_jdesc *jd, unsigned int start,
|
||||||
|
|
||||||
static void revoke_lo_after_scan(struct gfs2_jdesc *jd, int error, int pass)
|
static void revoke_lo_after_scan(struct gfs2_jdesc *jd, int error, int pass)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = jd->jd_inode->u.generic_ip;
|
struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
gfs2_revoke_clean(sdp);
|
gfs2_revoke_clean(sdp);
|
||||||
|
@ -465,7 +461,7 @@ static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le)
|
||||||
struct gfs2_bufdata *bd = container_of(le, struct gfs2_bufdata, bd_le);
|
struct gfs2_bufdata *bd = container_of(le, struct gfs2_bufdata, bd_le);
|
||||||
struct gfs2_trans *tr = current->journal_info;
|
struct gfs2_trans *tr = current->journal_info;
|
||||||
struct address_space *mapping = bd->bd_bh->b_page->mapping;
|
struct address_space *mapping = bd->bd_bh->b_page->mapping;
|
||||||
struct gfs2_inode *ip = mapping->host->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(mapping->host);
|
||||||
|
|
||||||
tr->tr_touched = 1;
|
tr->tr_touched = 1;
|
||||||
if (!list_empty(&bd->bd_list_tr) &&
|
if (!list_empty(&bd->bd_list_tr) &&
|
||||||
|
@ -665,8 +661,8 @@ static int databuf_lo_scan_elements(struct gfs2_jdesc *jd, unsigned int start,
|
||||||
struct gfs2_log_descriptor *ld,
|
struct gfs2_log_descriptor *ld,
|
||||||
__be64 *ptr, int pass)
|
__be64 *ptr, int pass)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = jd->jd_inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
|
||||||
struct gfs2_glock *gl = ip->i_gl;
|
struct gfs2_glock *gl = ip->i_gl;
|
||||||
unsigned int blks = be32_to_cpu(ld->ld_data1);
|
unsigned int blks = be32_to_cpu(ld->ld_data1);
|
||||||
struct buffer_head *bh_log, *bh_ip;
|
struct buffer_head *bh_log, *bh_ip;
|
||||||
|
@ -716,8 +712,8 @@ static int databuf_lo_scan_elements(struct gfs2_jdesc *jd, unsigned int start,
|
||||||
|
|
||||||
static void databuf_lo_after_scan(struct gfs2_jdesc *jd, int error, int pass)
|
static void databuf_lo_after_scan(struct gfs2_jdesc *jd, int error, int pass)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = jd->jd_inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
gfs2_meta_sync(ip->i_gl,
|
gfs2_meta_sync(ip->i_gl,
|
||||||
|
|
|
@ -29,8 +29,6 @@ static void gfs2_init_inode_once(void *foo, kmem_cache_t *cachep, unsigned long
|
||||||
if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
|
if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
|
||||||
SLAB_CTOR_CONSTRUCTOR) {
|
SLAB_CTOR_CONSTRUCTOR) {
|
||||||
inode_init_once(&ip->i_inode);
|
inode_init_once(&ip->i_inode);
|
||||||
atomic_set(&ip->i_count, 0);
|
|
||||||
ip->i_vnode = &ip->i_inode;
|
|
||||||
spin_lock_init(&ip->i_spin);
|
spin_lock_init(&ip->i_spin);
|
||||||
init_rwsem(&ip->i_rw_mutex);
|
init_rwsem(&ip->i_rw_mutex);
|
||||||
memset(ip->i_cache, 0, sizeof(ip->i_cache));
|
memset(ip->i_cache, 0, sizeof(ip->i_cache));
|
||||||
|
|
|
@ -91,9 +91,6 @@ static void stuck_releasepage(struct buffer_head *bh)
|
||||||
fs_warn(sdp, "ip = %llu %llu\n",
|
fs_warn(sdp, "ip = %llu %llu\n",
|
||||||
(unsigned long long)ip->i_num.no_formal_ino,
|
(unsigned long long)ip->i_num.no_formal_ino,
|
||||||
(unsigned long long)ip->i_num.no_addr);
|
(unsigned long long)ip->i_num.no_addr);
|
||||||
fs_warn(sdp, "ip->i_count = %d, ip->i_vnode = %s\n",
|
|
||||||
atomic_read(&ip->i_count),
|
|
||||||
(ip->i_vnode) ? "!NULL" : "NULL");
|
|
||||||
|
|
||||||
for (x = 0; x < GFS2_MAX_META_HEIGHT; x++)
|
for (x = 0; x < GFS2_MAX_META_HEIGHT; x++)
|
||||||
fs_warn(sdp, "ip->i_cache[%u] = %s\n",
|
fs_warn(sdp, "ip->i_cache[%u] = %s\n",
|
||||||
|
@ -567,7 +564,6 @@ void gfs2_attach_bufdata(struct gfs2_glock *gl, struct buffer_head *bh,
|
||||||
|
|
||||||
bd = kmem_cache_alloc(gfs2_bufdata_cachep, GFP_NOFS | __GFP_NOFAIL),
|
bd = kmem_cache_alloc(gfs2_bufdata_cachep, GFP_NOFS | __GFP_NOFAIL),
|
||||||
memset(bd, 0, sizeof(struct gfs2_bufdata));
|
memset(bd, 0, sizeof(struct gfs2_bufdata));
|
||||||
|
|
||||||
bd->bd_bh = bh;
|
bd->bd_bh = bh;
|
||||||
bd->bd_gl = gl;
|
bd->bd_gl = gl;
|
||||||
|
|
||||||
|
@ -664,7 +660,7 @@ void gfs2_unpin(struct gfs2_sbd *sdp, struct buffer_head *bh,
|
||||||
|
|
||||||
void gfs2_meta_wipe(struct gfs2_inode *ip, uint64_t bstart, uint32_t blen)
|
void gfs2_meta_wipe(struct gfs2_inode *ip, uint64_t bstart, uint32_t blen)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
||||||
struct inode *aspace = ip->i_gl->gl_aspace;
|
struct inode *aspace = ip->i_gl->gl_aspace;
|
||||||
struct buffer_head *bh;
|
struct buffer_head *bh;
|
||||||
|
|
||||||
|
@ -770,7 +766,7 @@ int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, uint64_t num,
|
||||||
if (new)
|
if (new)
|
||||||
meta_prep_new(bh);
|
meta_prep_new(bh);
|
||||||
else {
|
else {
|
||||||
error = gfs2_meta_reread(ip->i_sbd, bh,
|
error = gfs2_meta_reread(GFS2_SB(&ip->i_inode), bh,
|
||||||
DIO_START | DIO_WAIT);
|
DIO_START | DIO_WAIT);
|
||||||
if (error) {
|
if (error) {
|
||||||
brelse(bh);
|
brelse(bh);
|
||||||
|
@ -797,7 +793,7 @@ int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, uint64_t num,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (new) {
|
if (new) {
|
||||||
if (gfs2_assert_warn(ip->i_sbd, height)) {
|
if (gfs2_assert_warn(GFS2_SB(&ip->i_inode), height)) {
|
||||||
brelse(bh);
|
brelse(bh);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
@ -805,7 +801,7 @@ int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, uint64_t num,
|
||||||
gfs2_metatype_set(bh, GFS2_METATYPE_IN, GFS2_FORMAT_IN);
|
gfs2_metatype_set(bh, GFS2_METATYPE_IN, GFS2_FORMAT_IN);
|
||||||
gfs2_buffer_clear_tail(bh, sizeof(struct gfs2_meta_header));
|
gfs2_buffer_clear_tail(bh, sizeof(struct gfs2_meta_header));
|
||||||
|
|
||||||
} else if (gfs2_metatype_check(ip->i_sbd, bh,
|
} else if (gfs2_metatype_check(GFS2_SB(&ip->i_inode), bh,
|
||||||
(height) ? GFS2_METATYPE_IN : GFS2_METATYPE_DI)) {
|
(height) ? GFS2_METATYPE_IN : GFS2_METATYPE_DI)) {
|
||||||
brelse(bh);
|
brelse(bh);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
|
@ -293,23 +293,6 @@ void gfs2_statfs_change_out(struct gfs2_statfs_change *sc, char *buf)
|
||||||
str->sc_dinodes = cpu_to_be64(sc->sc_dinodes);
|
str->sc_dinodes = cpu_to_be64(sc->sc_dinodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gfs2_unlinked_tag_in(struct gfs2_unlinked_tag *ut, char *buf)
|
|
||||||
{
|
|
||||||
struct gfs2_unlinked_tag *str = (struct gfs2_unlinked_tag *)buf;
|
|
||||||
|
|
||||||
gfs2_inum_in(&ut->ut_inum, buf);
|
|
||||||
ut->ut_flags = be32_to_cpu(str->ut_flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
void gfs2_unlinked_tag_out(struct gfs2_unlinked_tag *ut, char *buf)
|
|
||||||
{
|
|
||||||
struct gfs2_unlinked_tag *str = (struct gfs2_unlinked_tag *)buf;
|
|
||||||
|
|
||||||
gfs2_inum_out(&ut->ut_inum, buf);
|
|
||||||
str->ut_flags = cpu_to_be32(ut->ut_flags);
|
|
||||||
str->__pad = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void gfs2_quota_change_in(struct gfs2_quota_change *qc, char *buf)
|
void gfs2_quota_change_in(struct gfs2_quota_change *qc, char *buf)
|
||||||
{
|
{
|
||||||
struct gfs2_quota_change *str = (struct gfs2_quota_change *)buf;
|
struct gfs2_quota_change *str = (struct gfs2_quota_change *)buf;
|
||||||
|
|
|
@ -81,7 +81,6 @@ int gfs2_get_block(struct inode *inode, sector_t lblock,
|
||||||
static int get_block_noalloc(struct inode *inode, sector_t lblock,
|
static int get_block_noalloc(struct inode *inode, sector_t lblock,
|
||||||
struct buffer_head *bh_result, int create)
|
struct buffer_head *bh_result, int create)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = inode->u.generic_ip;
|
|
||||||
int new = 0;
|
int new = 0;
|
||||||
uint64_t dblock;
|
uint64_t dblock;
|
||||||
int error;
|
int error;
|
||||||
|
@ -93,7 +92,7 @@ static int get_block_noalloc(struct inode *inode, sector_t lblock,
|
||||||
|
|
||||||
if (dblock)
|
if (dblock)
|
||||||
map_bh(bh_result, inode->i_sb, dblock);
|
map_bh(bh_result, inode->i_sb, dblock);
|
||||||
else if (gfs2_assert_withdraw(ip->i_sbd, !create))
|
else if (gfs2_assert_withdraw(GFS2_SB(inode), !create))
|
||||||
error = -EIO;
|
error = -EIO;
|
||||||
if (boundary)
|
if (boundary)
|
||||||
set_buffer_boundary(bh_result);
|
set_buffer_boundary(bh_result);
|
||||||
|
@ -114,8 +113,8 @@ static int get_block_noalloc(struct inode *inode, sector_t lblock,
|
||||||
static int gfs2_writepage(struct page *page, struct writeback_control *wbc)
|
static int gfs2_writepage(struct page *page, struct writeback_control *wbc)
|
||||||
{
|
{
|
||||||
struct inode *inode = page->mapping->host;
|
struct inode *inode = page->mapping->host;
|
||||||
struct gfs2_inode *ip = page->mapping->host->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(page->mapping->host);
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(page->mapping->host);
|
||||||
loff_t i_size = i_size_read(inode);
|
loff_t i_size = i_size_read(inode);
|
||||||
pgoff_t end_index = i_size >> PAGE_CACHE_SHIFT;
|
pgoff_t end_index = i_size >> PAGE_CACHE_SHIFT;
|
||||||
unsigned offset;
|
unsigned offset;
|
||||||
|
@ -216,8 +215,8 @@ static int stuffed_readpage(struct gfs2_inode *ip, struct page *page)
|
||||||
|
|
||||||
static int gfs2_readpage(struct file *file, struct page *page)
|
static int gfs2_readpage(struct file *file, struct page *page)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = page->mapping->host->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(page->mapping->host);
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(page->mapping->host);
|
||||||
struct gfs2_holder gh;
|
struct gfs2_holder gh;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
@ -271,8 +270,8 @@ static int gfs2_readpages(struct file *file, struct address_space *mapping,
|
||||||
struct list_head *pages, unsigned nr_pages)
|
struct list_head *pages, unsigned nr_pages)
|
||||||
{
|
{
|
||||||
struct inode *inode = mapping->host;
|
struct inode *inode = mapping->host;
|
||||||
struct gfs2_inode *ip = inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(inode);
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(inode);
|
||||||
struct gfs2_holder gh;
|
struct gfs2_holder gh;
|
||||||
unsigned page_idx;
|
unsigned page_idx;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -345,8 +344,8 @@ out_unlock:
|
||||||
static int gfs2_prepare_write(struct file *file, struct page *page,
|
static int gfs2_prepare_write(struct file *file, struct page *page,
|
||||||
unsigned from, unsigned to)
|
unsigned from, unsigned to)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = page->mapping->host->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(page->mapping->host);
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(page->mapping->host);
|
||||||
unsigned int data_blocks, ind_blocks, rblocks;
|
unsigned int data_blocks, ind_blocks, rblocks;
|
||||||
int alloc_required;
|
int alloc_required;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
@ -440,8 +439,8 @@ static int gfs2_commit_write(struct file *file, struct page *page,
|
||||||
unsigned from, unsigned to)
|
unsigned from, unsigned to)
|
||||||
{
|
{
|
||||||
struct inode *inode = page->mapping->host;
|
struct inode *inode = page->mapping->host;
|
||||||
struct gfs2_inode *ip = inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(inode);
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(inode);
|
||||||
int error = -EOPNOTSUPP;
|
int error = -EOPNOTSUPP;
|
||||||
struct buffer_head *dibh;
|
struct buffer_head *dibh;
|
||||||
struct gfs2_alloc *al = &ip->i_alloc;;
|
struct gfs2_alloc *al = &ip->i_alloc;;
|
||||||
|
@ -520,7 +519,7 @@ fail_nounlock:
|
||||||
|
|
||||||
static sector_t gfs2_bmap(struct address_space *mapping, sector_t lblock)
|
static sector_t gfs2_bmap(struct address_space *mapping, sector_t lblock)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = mapping->host->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(mapping->host);
|
||||||
struct gfs2_holder i_gh;
|
struct gfs2_holder i_gh;
|
||||||
sector_t dblock = 0;
|
sector_t dblock = 0;
|
||||||
int error;
|
int error;
|
||||||
|
@ -594,7 +593,7 @@ static ssize_t gfs2_direct_IO_write(struct kiocb *iocb, const struct iovec *iov,
|
||||||
{
|
{
|
||||||
struct file *file = iocb->ki_filp;
|
struct file *file = iocb->ki_filp;
|
||||||
struct inode *inode = file->f_mapping->host;
|
struct inode *inode = file->f_mapping->host;
|
||||||
struct gfs2_inode *ip = inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(inode);
|
||||||
struct gfs2_holder gh;
|
struct gfs2_holder gh;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
|
@ -641,8 +640,8 @@ static ssize_t gfs2_direct_IO(int rw, struct kiocb *iocb,
|
||||||
{
|
{
|
||||||
struct file *file = iocb->ki_filp;
|
struct file *file = iocb->ki_filp;
|
||||||
struct inode *inode = file->f_mapping->host;
|
struct inode *inode = file->f_mapping->host;
|
||||||
struct gfs2_inode *ip = inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(inode);
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(inode);
|
||||||
|
|
||||||
if (rw == WRITE)
|
if (rw == WRITE)
|
||||||
return gfs2_direct_IO_write(iocb, iov, offset, nr_segs);
|
return gfs2_direct_IO_write(iocb, iov, offset, nr_segs);
|
||||||
|
|
|
@ -38,8 +38,8 @@
|
||||||
static int gfs2_drevalidate(struct dentry *dentry, struct nameidata *nd)
|
static int gfs2_drevalidate(struct dentry *dentry, struct nameidata *nd)
|
||||||
{
|
{
|
||||||
struct dentry *parent = dget_parent(dentry);
|
struct dentry *parent = dget_parent(dentry);
|
||||||
struct gfs2_sbd *sdp = parent->d_inode->i_sb->s_fs_info;
|
struct gfs2_sbd *sdp = GFS2_SB(parent->d_inode);
|
||||||
struct gfs2_inode *dip = parent->d_inode->u.generic_ip;
|
struct gfs2_inode *dip = GFS2_I(parent->d_inode);
|
||||||
struct inode *inode = dentry->d_inode;
|
struct inode *inode = dentry->d_inode;
|
||||||
struct gfs2_holder d_gh;
|
struct gfs2_holder d_gh;
|
||||||
struct gfs2_inode *ip;
|
struct gfs2_inode *ip;
|
||||||
|
@ -71,7 +71,7 @@ static int gfs2_drevalidate(struct dentry *dentry, struct nameidata *nd)
|
||||||
goto fail_gunlock;
|
goto fail_gunlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
ip = inode->u.generic_ip;
|
ip = GFS2_I(inode);
|
||||||
|
|
||||||
if (!gfs2_inum_equal(&ip->i_num, &inum))
|
if (!gfs2_inum_equal(&ip->i_num, &inum))
|
||||||
goto invalid_gunlock;
|
goto invalid_gunlock;
|
||||||
|
|
|
@ -66,7 +66,7 @@ static int gfs2_encode_fh(struct dentry *dentry, __u32 *fh, int *len,
|
||||||
{
|
{
|
||||||
struct inode *inode = dentry->d_inode;
|
struct inode *inode = dentry->d_inode;
|
||||||
struct super_block *sb = inode->i_sb;
|
struct super_block *sb = inode->i_sb;
|
||||||
struct gfs2_inode *ip = inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(inode);
|
||||||
|
|
||||||
if (*len < 4 || (connectable && *len < 8))
|
if (*len < 4 || (connectable && *len < 8))
|
||||||
return 255;
|
return 255;
|
||||||
|
@ -86,8 +86,8 @@ static int gfs2_encode_fh(struct dentry *dentry, __u32 *fh, int *len,
|
||||||
|
|
||||||
spin_lock(&dentry->d_lock);
|
spin_lock(&dentry->d_lock);
|
||||||
inode = dentry->d_parent->d_inode;
|
inode = dentry->d_parent->d_inode;
|
||||||
ip = inode->u.generic_ip;
|
ip = GFS2_I(inode);
|
||||||
gfs2_inode_hold(ip);
|
igrab(inode);
|
||||||
spin_unlock(&dentry->d_lock);
|
spin_unlock(&dentry->d_lock);
|
||||||
|
|
||||||
fh[4] = ip->i_num.no_formal_ino >> 32;
|
fh[4] = ip->i_num.no_formal_ino >> 32;
|
||||||
|
@ -100,7 +100,7 @@ static int gfs2_encode_fh(struct dentry *dentry, __u32 *fh, int *len,
|
||||||
fh[7] = cpu_to_be32(fh[7]);
|
fh[7] = cpu_to_be32(fh[7]);
|
||||||
*len = 8;
|
*len = 8;
|
||||||
|
|
||||||
gfs2_inode_put(ip);
|
iput(inode);
|
||||||
|
|
||||||
return *len;
|
return *len;
|
||||||
}
|
}
|
||||||
|
@ -142,8 +142,8 @@ static int gfs2_get_name(struct dentry *parent, char *name,
|
||||||
if (!S_ISDIR(dir->i_mode) || !inode)
|
if (!S_ISDIR(dir->i_mode) || !inode)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
dip = dir->u.generic_ip;
|
dip = GFS2_I(dir);
|
||||||
ip = inode->u.generic_ip;
|
ip = GFS2_I(inode);
|
||||||
|
|
||||||
*name = 0;
|
*name = 0;
|
||||||
gnfd.inum = ip->i_num;
|
gnfd.inum = ip->i_num;
|
||||||
|
@ -189,39 +189,30 @@ static struct dentry *gfs2_get_parent(struct dentry *child)
|
||||||
static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_p)
|
static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_p)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = sb->s_fs_info;
|
struct gfs2_sbd *sdp = sb->s_fs_info;
|
||||||
struct gfs2_inum *inum = (struct gfs2_inum *)inum_p;
|
struct gfs2_inum *inum = inum_p;
|
||||||
struct gfs2_holder i_gh, ri_gh, rgd_gh;
|
struct gfs2_holder i_gh, ri_gh, rgd_gh;
|
||||||
struct gfs2_rgrpd *rgd;
|
struct gfs2_rgrpd *rgd;
|
||||||
struct gfs2_inode *ip;
|
|
||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
struct dentry *dentry;
|
struct dentry *dentry;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
/* System files? */
|
/* System files? */
|
||||||
|
|
||||||
inode = gfs2_iget(sb, inum);
|
inode = gfs2_ilookup(sb, inum);
|
||||||
if (inode) {
|
if (inode) {
|
||||||
ip = inode->u.generic_ip;
|
if (GFS2_I(inode)->i_num.no_formal_ino != inum->no_formal_ino) {
|
||||||
if (ip->i_num.no_formal_ino != inum->no_formal_ino) {
|
|
||||||
iput(inode);
|
iput(inode);
|
||||||
return ERR_PTR(-ESTALE);
|
return ERR_PTR(-ESTALE);
|
||||||
}
|
}
|
||||||
goto out_inode;
|
goto out_inode;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = gfs2_glock_nq_num(sdp,
|
error = gfs2_glock_nq_num(sdp, inum->no_addr, &gfs2_inode_glops,
|
||||||
inum->no_addr, &gfs2_inode_glops,
|
|
||||||
LM_ST_SHARED, LM_FLAG_ANY | GL_LOCAL_EXCL,
|
LM_ST_SHARED, LM_FLAG_ANY | GL_LOCAL_EXCL,
|
||||||
&i_gh);
|
&i_gh);
|
||||||
if (error)
|
if (error)
|
||||||
return ERR_PTR(error);
|
return ERR_PTR(error);
|
||||||
|
|
||||||
error = gfs2_inode_get(i_gh.gh_gl, inum, NO_CREATE, &ip);
|
|
||||||
if (error)
|
|
||||||
goto fail;
|
|
||||||
if (ip)
|
|
||||||
goto out_ip;
|
|
||||||
|
|
||||||
error = gfs2_rindex_hold(sdp, &ri_gh);
|
error = gfs2_rindex_hold(sdp, &ri_gh);
|
||||||
if (error)
|
if (error)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -242,32 +233,29 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_p)
|
||||||
gfs2_glock_dq_uninit(&rgd_gh);
|
gfs2_glock_dq_uninit(&rgd_gh);
|
||||||
gfs2_glock_dq_uninit(&ri_gh);
|
gfs2_glock_dq_uninit(&ri_gh);
|
||||||
|
|
||||||
error = gfs2_inode_get(i_gh.gh_gl, inum, CREATE, &ip);
|
inode = gfs2_inode_lookup(sb, inum, DT_UNKNOWN);
|
||||||
if (error)
|
if (!inode)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
if (IS_ERR(inode)) {
|
||||||
error = gfs2_inode_refresh(ip);
|
error = PTR_ERR(inode);
|
||||||
if (error) {
|
goto fail;
|
||||||
gfs2_inode_put(ip);
|
}
|
||||||
|
|
||||||
|
error = gfs2_inode_refresh(GFS2_I(inode));
|
||||||
|
if (error) {
|
||||||
|
iput(inode);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
out_ip:
|
|
||||||
error = -EIO;
|
error = -EIO;
|
||||||
if (ip->i_di.di_flags & GFS2_DIF_SYSTEM) {
|
if (GFS2_I(inode)->i_di.di_flags & GFS2_DIF_SYSTEM) {
|
||||||
gfs2_inode_put(ip);
|
iput(inode);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
gfs2_glock_dq_uninit(&i_gh);
|
gfs2_glock_dq_uninit(&i_gh);
|
||||||
|
|
||||||
inode = gfs2_ip2v(ip);
|
out_inode:
|
||||||
gfs2_inode_put(ip);
|
|
||||||
|
|
||||||
if (!inode)
|
|
||||||
return ERR_PTR(-ENOMEM);
|
|
||||||
|
|
||||||
out_inode:
|
|
||||||
dentry = d_alloc_anon(inode);
|
dentry = d_alloc_anon(inode);
|
||||||
if (!dentry) {
|
if (!dentry) {
|
||||||
iput(inode);
|
iput(inode);
|
||||||
|
@ -276,13 +264,13 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_p)
|
||||||
|
|
||||||
return dentry;
|
return dentry;
|
||||||
|
|
||||||
fail_rgd:
|
fail_rgd:
|
||||||
gfs2_glock_dq_uninit(&rgd_gh);
|
gfs2_glock_dq_uninit(&rgd_gh);
|
||||||
|
|
||||||
fail_rindex:
|
fail_rindex:
|
||||||
gfs2_glock_dq_uninit(&ri_gh);
|
gfs2_glock_dq_uninit(&ri_gh);
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
gfs2_glock_dq_uninit(&i_gh);
|
gfs2_glock_dq_uninit(&i_gh);
|
||||||
return ERR_PTR(error);
|
return ERR_PTR(error);
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,7 +105,7 @@ static int gfs2_read_actor(read_descriptor_t *desc, struct page *page,
|
||||||
int gfs2_internal_read(struct gfs2_inode *ip, struct file_ra_state *ra_state,
|
int gfs2_internal_read(struct gfs2_inode *ip, struct file_ra_state *ra_state,
|
||||||
char *buf, loff_t *pos, unsigned size)
|
char *buf, loff_t *pos, unsigned size)
|
||||||
{
|
{
|
||||||
struct inode *inode = ip->i_vnode;
|
struct inode *inode = &ip->i_inode;
|
||||||
read_descriptor_t desc;
|
read_descriptor_t desc;
|
||||||
desc.written = 0;
|
desc.written = 0;
|
||||||
desc.arg.buf = buf;
|
desc.arg.buf = buf;
|
||||||
|
@ -131,7 +131,7 @@ int gfs2_internal_read(struct gfs2_inode *ip, struct file_ra_state *ra_state,
|
||||||
|
|
||||||
static loff_t gfs2_llseek(struct file *file, loff_t offset, int origin)
|
static loff_t gfs2_llseek(struct file *file, loff_t offset, int origin)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = file->f_mapping->host->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(file->f_mapping->host);
|
||||||
struct gfs2_holder i_gh;
|
struct gfs2_holder i_gh;
|
||||||
loff_t error;
|
loff_t error;
|
||||||
|
|
||||||
|
@ -178,7 +178,7 @@ static ssize_t __gfs2_file_aio_read(struct kiocb *iocb,
|
||||||
unsigned long nr_segs, loff_t *ppos)
|
unsigned long nr_segs, loff_t *ppos)
|
||||||
{
|
{
|
||||||
struct file *filp = iocb->ki_filp;
|
struct file *filp = iocb->ki_filp;
|
||||||
struct gfs2_inode *ip = filp->f_mapping->host->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(filp->f_mapping->host);
|
||||||
struct gfs2_holder gh;
|
struct gfs2_holder gh;
|
||||||
ssize_t retval;
|
ssize_t retval;
|
||||||
unsigned long seg;
|
unsigned long seg;
|
||||||
|
@ -361,13 +361,13 @@ static int filldir_reg_func(void *opaque, const char *name, unsigned int length,
|
||||||
static int readdir_reg(struct file *file, void *dirent, filldir_t filldir)
|
static int readdir_reg(struct file *file, void *dirent, filldir_t filldir)
|
||||||
{
|
{
|
||||||
struct inode *dir = file->f_mapping->host;
|
struct inode *dir = file->f_mapping->host;
|
||||||
struct gfs2_inode *dip = dir->u.generic_ip;
|
struct gfs2_inode *dip = GFS2_I(dir);
|
||||||
struct filldir_reg fdr;
|
struct filldir_reg fdr;
|
||||||
struct gfs2_holder d_gh;
|
struct gfs2_holder d_gh;
|
||||||
uint64_t offset = file->f_pos;
|
uint64_t offset = file->f_pos;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
fdr.fdr_sbd = dip->i_sbd;
|
fdr.fdr_sbd = GFS2_SB(dir);
|
||||||
fdr.fdr_prefetch = 1;
|
fdr.fdr_prefetch = 1;
|
||||||
fdr.fdr_filldir = filldir;
|
fdr.fdr_filldir = filldir;
|
||||||
fdr.fdr_opaque = dirent;
|
fdr.fdr_opaque = dirent;
|
||||||
|
@ -451,8 +451,8 @@ static int filldir_bad_func(void *opaque, const char *name, unsigned int length,
|
||||||
static int readdir_bad(struct file *file, void *dirent, filldir_t filldir)
|
static int readdir_bad(struct file *file, void *dirent, filldir_t filldir)
|
||||||
{
|
{
|
||||||
struct inode *dir = file->f_mapping->host;
|
struct inode *dir = file->f_mapping->host;
|
||||||
struct gfs2_inode *dip = dir->u.generic_ip;
|
struct gfs2_inode *dip = GFS2_I(dir);
|
||||||
struct gfs2_sbd *sdp = dip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(dir);
|
||||||
struct filldir_reg fdr;
|
struct filldir_reg fdr;
|
||||||
unsigned int entries, size;
|
unsigned int entries, size;
|
||||||
struct filldir_bad *fdb;
|
struct filldir_bad *fdb;
|
||||||
|
@ -561,7 +561,7 @@ static const u32 gfs2_to_iflags[32] = {
|
||||||
static int gfs2_get_flags(struct file *filp, u32 __user *ptr)
|
static int gfs2_get_flags(struct file *filp, u32 __user *ptr)
|
||||||
{
|
{
|
||||||
struct inode *inode = filp->f_dentry->d_inode;
|
struct inode *inode = filp->f_dentry->d_inode;
|
||||||
struct gfs2_inode *ip = inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(inode);
|
||||||
struct gfs2_holder gh;
|
struct gfs2_holder gh;
|
||||||
int error;
|
int error;
|
||||||
u32 iflags;
|
u32 iflags;
|
||||||
|
@ -601,8 +601,8 @@ static int gfs2_get_flags(struct file *filp, u32 __user *ptr)
|
||||||
static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask)
|
static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask)
|
||||||
{
|
{
|
||||||
struct inode *inode = filp->f_dentry->d_inode;
|
struct inode *inode = filp->f_dentry->d_inode;
|
||||||
struct gfs2_inode *ip = inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(inode);
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(inode);
|
||||||
struct buffer_head *bh;
|
struct buffer_head *bh;
|
||||||
struct gfs2_holder gh;
|
struct gfs2_holder gh;
|
||||||
int error;
|
int error;
|
||||||
|
@ -693,7 +693,7 @@ static long gfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
||||||
|
|
||||||
static int gfs2_mmap(struct file *file, struct vm_area_struct *vma)
|
static int gfs2_mmap(struct file *file, struct vm_area_struct *vma)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = file->f_mapping->host->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(file->f_mapping->host);
|
||||||
struct gfs2_holder i_gh;
|
struct gfs2_holder i_gh;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
@ -728,7 +728,7 @@ static int gfs2_mmap(struct file *file, struct vm_area_struct *vma)
|
||||||
|
|
||||||
static int gfs2_open(struct inode *inode, struct file *file)
|
static int gfs2_open(struct inode *inode, struct file *file)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(inode);
|
||||||
struct gfs2_holder i_gh;
|
struct gfs2_holder i_gh;
|
||||||
struct gfs2_file *fp;
|
struct gfs2_file *fp;
|
||||||
int error;
|
int error;
|
||||||
|
@ -739,7 +739,7 @@ static int gfs2_open(struct inode *inode, struct file *file)
|
||||||
|
|
||||||
mutex_init(&fp->f_fl_mutex);
|
mutex_init(&fp->f_fl_mutex);
|
||||||
|
|
||||||
gfs2_assert_warn(ip->i_sbd, !file->private_data);
|
gfs2_assert_warn(GFS2_SB(inode), !file->private_data);
|
||||||
file->private_data = fp;
|
file->private_data = fp;
|
||||||
|
|
||||||
if (S_ISREG(ip->i_di.di_mode)) {
|
if (S_ISREG(ip->i_di.di_mode)) {
|
||||||
|
@ -808,7 +808,7 @@ static int gfs2_close(struct inode *inode, struct file *file)
|
||||||
|
|
||||||
static int gfs2_fsync(struct file *file, struct dentry *dentry, int datasync)
|
static int gfs2_fsync(struct file *file, struct dentry *dentry, int datasync)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = dentry->d_inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(dentry->d_inode);
|
||||||
|
|
||||||
gfs2_log_flush(ip->i_gl->gl_sbd, ip->i_gl);
|
gfs2_log_flush(ip->i_gl->gl_sbd, ip->i_gl);
|
||||||
|
|
||||||
|
@ -826,8 +826,8 @@ static int gfs2_fsync(struct file *file, struct dentry *dentry, int datasync)
|
||||||
|
|
||||||
static int gfs2_lock(struct file *file, int cmd, struct file_lock *fl)
|
static int gfs2_lock(struct file *file, int cmd, struct file_lock *fl)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = file->f_mapping->host->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(file->f_mapping->host);
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(file->f_mapping->host);
|
||||||
struct lm_lockname name =
|
struct lm_lockname name =
|
||||||
{ .ln_number = ip->i_num.no_addr,
|
{ .ln_number = ip->i_num.no_addr,
|
||||||
.ln_type = LM_TYPE_PLOCK };
|
.ln_type = LM_TYPE_PLOCK };
|
||||||
|
@ -881,7 +881,7 @@ static int do_flock(struct file *file, int cmd, struct file_lock *fl)
|
||||||
{
|
{
|
||||||
struct gfs2_file *fp = file->private_data;
|
struct gfs2_file *fp = file->private_data;
|
||||||
struct gfs2_holder *fl_gh = &fp->f_fl_gh;
|
struct gfs2_holder *fl_gh = &fp->f_fl_gh;
|
||||||
struct gfs2_inode *ip = file->f_dentry->d_inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(file->f_dentry->d_inode);
|
||||||
struct gfs2_glock *gl;
|
struct gfs2_glock *gl;
|
||||||
unsigned int state;
|
unsigned int state;
|
||||||
int flags;
|
int flags;
|
||||||
|
@ -901,7 +901,7 @@ static int do_flock(struct file *file, int cmd, struct file_lock *fl)
|
||||||
&(struct file_lock){.fl_type = F_UNLCK});
|
&(struct file_lock){.fl_type = F_UNLCK});
|
||||||
gfs2_glock_dq_uninit(fl_gh);
|
gfs2_glock_dq_uninit(fl_gh);
|
||||||
} else {
|
} else {
|
||||||
error = gfs2_glock_get(ip->i_sbd,
|
error = gfs2_glock_get(GFS2_SB(&ip->i_inode),
|
||||||
ip->i_num.no_addr, &gfs2_flock_glops,
|
ip->i_num.no_addr, &gfs2_flock_glops,
|
||||||
CREATE, &gl);
|
CREATE, &gl);
|
||||||
if (error)
|
if (error)
|
||||||
|
@ -918,7 +918,7 @@ static int do_flock(struct file *file, int cmd, struct file_lock *fl)
|
||||||
error = -EAGAIN;
|
error = -EAGAIN;
|
||||||
} else {
|
} else {
|
||||||
error = flock_lock_file_wait(file, fl);
|
error = flock_lock_file_wait(file, fl);
|
||||||
gfs2_assert_warn(ip->i_sbd, !error);
|
gfs2_assert_warn(GFS2_SB(&ip->i_inode), !error);
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
@ -950,8 +950,8 @@ static void do_unflock(struct file *file, struct file_lock *fl)
|
||||||
|
|
||||||
static int gfs2_flock(struct file *file, int cmd, struct file_lock *fl)
|
static int gfs2_flock(struct file *file, int cmd, struct file_lock *fl)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = file->f_mapping->host->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(file->f_mapping->host);
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(file->f_mapping->host);
|
||||||
|
|
||||||
if (!(fl->fl_flags & FL_FLOCK))
|
if (!(fl->fl_flags & FL_FLOCK))
|
||||||
return -ENOLCK;
|
return -ENOLCK;
|
||||||
|
|
|
@ -32,7 +32,6 @@
|
||||||
#include "recovery.h"
|
#include "recovery.h"
|
||||||
#include "rgrp.h"
|
#include "rgrp.h"
|
||||||
#include "super.h"
|
#include "super.h"
|
||||||
#include "unlinked.h"
|
|
||||||
#include "sys.h"
|
#include "sys.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
@ -80,10 +79,6 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb)
|
||||||
spin_lock_init(&sdp->sd_jindex_spin);
|
spin_lock_init(&sdp->sd_jindex_spin);
|
||||||
mutex_init(&sdp->sd_jindex_mutex);
|
mutex_init(&sdp->sd_jindex_mutex);
|
||||||
|
|
||||||
INIT_LIST_HEAD(&sdp->sd_unlinked_list);
|
|
||||||
spin_lock_init(&sdp->sd_unlinked_spin);
|
|
||||||
mutex_init(&sdp->sd_unlinked_mutex);
|
|
||||||
|
|
||||||
INIT_LIST_HEAD(&sdp->sd_quota_list);
|
INIT_LIST_HEAD(&sdp->sd_quota_list);
|
||||||
spin_lock_init(&sdp->sd_quota_spin);
|
spin_lock_init(&sdp->sd_quota_spin);
|
||||||
mutex_init(&sdp->sd_quota_mutex);
|
mutex_init(&sdp->sd_quota_mutex);
|
||||||
|
@ -248,19 +243,19 @@ static int init_locking(struct gfs2_sbd *sdp, struct gfs2_holder *mount_gh,
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail_trans:
|
fail_trans:
|
||||||
gfs2_glock_put(sdp->sd_trans_gl);
|
gfs2_glock_put(sdp->sd_trans_gl);
|
||||||
|
|
||||||
fail_rename:
|
fail_rename:
|
||||||
gfs2_glock_put(sdp->sd_rename_gl);
|
gfs2_glock_put(sdp->sd_rename_gl);
|
||||||
|
|
||||||
fail_live:
|
fail_live:
|
||||||
gfs2_glock_dq_uninit(&sdp->sd_live_gh);
|
gfs2_glock_dq_uninit(&sdp->sd_live_gh);
|
||||||
|
|
||||||
fail_mount:
|
fail_mount:
|
||||||
gfs2_glock_dq_uninit(mount_gh);
|
gfs2_glock_dq_uninit(mount_gh);
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
while (sdp->sd_glockd_num--)
|
while (sdp->sd_glockd_num--)
|
||||||
kthread_stop(sdp->sd_glockd_process[sdp->sd_glockd_num]);
|
kthread_stop(sdp->sd_glockd_process[sdp->sd_glockd_num]);
|
||||||
|
|
||||||
|
@ -269,28 +264,10 @@ static int init_locking(struct gfs2_sbd *sdp, struct gfs2_holder *mount_gh,
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct inode *gfs2_lookup_root(struct gfs2_sbd *sdp,
|
static struct inode *gfs2_lookup_root(struct super_block *sb,
|
||||||
const struct gfs2_inum *inum)
|
struct gfs2_inum *inum)
|
||||||
{
|
{
|
||||||
int error;
|
return gfs2_inode_lookup(sb, inum, DT_DIR);
|
||||||
struct gfs2_glock *gl;
|
|
||||||
struct gfs2_inode *ip;
|
|
||||||
struct inode *inode;
|
|
||||||
|
|
||||||
error = gfs2_glock_get(sdp, inum->no_addr, &gfs2_inode_glops,
|
|
||||||
CREATE, &gl);
|
|
||||||
if (!error) {
|
|
||||||
error = gfs2_inode_get(gl, inum, CREATE, &ip);
|
|
||||||
if (!error) {
|
|
||||||
gfs2_inode_min_init(ip, DT_DIR);
|
|
||||||
inode = gfs2_ip2v(ip);
|
|
||||||
gfs2_inode_put(ip);
|
|
||||||
gfs2_glock_put(gl);
|
|
||||||
return inode;
|
|
||||||
}
|
|
||||||
gfs2_glock_put(gl);
|
|
||||||
}
|
|
||||||
return ERR_PTR(error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int init_sb(struct gfs2_sbd *sdp, int silent, int undo)
|
static int init_sb(struct gfs2_sbd *sdp, int silent, int undo)
|
||||||
|
@ -305,8 +282,7 @@ static int init_sb(struct gfs2_sbd *sdp, int silent, int undo)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = gfs2_glock_nq_num(sdp,
|
error = gfs2_glock_nq_num(sdp, GFS2_SB_LOCK, &gfs2_meta_glops,
|
||||||
GFS2_SB_LOCK, &gfs2_meta_glops,
|
|
||||||
LM_ST_SHARED, 0, &sb_gh);
|
LM_ST_SHARED, 0, &sb_gh);
|
||||||
if (error) {
|
if (error) {
|
||||||
fs_err(sdp, "can't acquire superblock glock: %d\n", error);
|
fs_err(sdp, "can't acquire superblock glock: %d\n", error);
|
||||||
|
@ -345,7 +321,7 @@ static int init_sb(struct gfs2_sbd *sdp, int silent, int undo)
|
||||||
inum = &sdp->sd_sb.sb_root_dir;
|
inum = &sdp->sd_sb.sb_root_dir;
|
||||||
if (sb->s_type == &gfs2meta_fs_type)
|
if (sb->s_type == &gfs2meta_fs_type)
|
||||||
inum = &sdp->sd_sb.sb_master_dir;
|
inum = &sdp->sd_sb.sb_master_dir;
|
||||||
inode = gfs2_lookup_root(sdp, inum);
|
inode = gfs2_lookup_root(sb, inum);
|
||||||
if (IS_ERR(inode)) {
|
if (IS_ERR(inode)) {
|
||||||
error = PTR_ERR(inode);
|
error = PTR_ERR(inode);
|
||||||
fs_err(sdp, "can't read in root inode: %d\n", error);
|
fs_err(sdp, "can't read in root inode: %d\n", error);
|
||||||
|
@ -382,7 +358,7 @@ static int init_journal(struct gfs2_sbd *sdp, int undo)
|
||||||
fs_err(sdp, "can't lookup journal index: %d\n", error);
|
fs_err(sdp, "can't lookup journal index: %d\n", error);
|
||||||
return PTR_ERR(sdp->sd_jindex);
|
return PTR_ERR(sdp->sd_jindex);
|
||||||
}
|
}
|
||||||
ip = sdp->sd_jindex->u.generic_ip;
|
ip = GFS2_I(sdp->sd_jindex);
|
||||||
set_bit(GLF_STICKY, &ip->i_gl->gl_flags);
|
set_bit(GLF_STICKY, &ip->i_gl->gl_flags);
|
||||||
|
|
||||||
/* Load in the journal index special file */
|
/* Load in the journal index special file */
|
||||||
|
@ -413,8 +389,7 @@ static int init_journal(struct gfs2_sbd *sdp, int undo)
|
||||||
}
|
}
|
||||||
sdp->sd_jdesc = gfs2_jdesc_find(sdp, sdp->sd_lockstruct.ls_jid);
|
sdp->sd_jdesc = gfs2_jdesc_find(sdp, sdp->sd_lockstruct.ls_jid);
|
||||||
|
|
||||||
error = gfs2_glock_nq_num(sdp,
|
error = gfs2_glock_nq_num(sdp, sdp->sd_lockstruct.ls_jid,
|
||||||
sdp->sd_lockstruct.ls_jid,
|
|
||||||
&gfs2_journal_glops,
|
&gfs2_journal_glops,
|
||||||
LM_ST_EXCLUSIVE, LM_FLAG_NOEXP,
|
LM_ST_EXCLUSIVE, LM_FLAG_NOEXP,
|
||||||
&sdp->sd_journal_gh);
|
&sdp->sd_journal_gh);
|
||||||
|
@ -423,9 +398,8 @@ static int init_journal(struct gfs2_sbd *sdp, int undo)
|
||||||
goto fail_jindex;
|
goto fail_jindex;
|
||||||
}
|
}
|
||||||
|
|
||||||
ip = sdp->sd_jdesc->jd_inode->u.generic_ip;
|
ip = GFS2_I(sdp->sd_jdesc->jd_inode);
|
||||||
error = gfs2_glock_nq_init(ip->i_gl,
|
error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED,
|
||||||
LM_ST_SHARED,
|
|
||||||
LM_FLAG_NOEXP | GL_EXACT,
|
LM_FLAG_NOEXP | GL_EXACT,
|
||||||
&sdp->sd_jinode_gh);
|
&sdp->sd_jinode_gh);
|
||||||
if (error) {
|
if (error) {
|
||||||
|
@ -509,7 +483,7 @@ static int init_inodes(struct gfs2_sbd *sdp, int undo)
|
||||||
if (undo)
|
if (undo)
|
||||||
goto fail_qinode;
|
goto fail_qinode;
|
||||||
|
|
||||||
inode = gfs2_lookup_root(sdp, &sdp->sd_sb.sb_master_dir);
|
inode = gfs2_lookup_root(sdp->sd_vfs, &sdp->sd_sb.sb_master_dir);
|
||||||
if (IS_ERR(inode)) {
|
if (IS_ERR(inode)) {
|
||||||
error = PTR_ERR(inode);
|
error = PTR_ERR(inode);
|
||||||
fs_err(sdp, "can't read in master directory: %d\n", error);
|
fs_err(sdp, "can't read in master directory: %d\n", error);
|
||||||
|
@ -545,7 +519,7 @@ static int init_inodes(struct gfs2_sbd *sdp, int undo)
|
||||||
fs_err(sdp, "can't get resource index inode: %d\n", error);
|
fs_err(sdp, "can't get resource index inode: %d\n", error);
|
||||||
goto fail_statfs;
|
goto fail_statfs;
|
||||||
}
|
}
|
||||||
ip = sdp->sd_rindex->u.generic_ip;
|
ip = GFS2_I(sdp->sd_rindex);
|
||||||
set_bit(GLF_STICKY, &ip->i_gl->gl_flags);
|
set_bit(GLF_STICKY, &ip->i_gl->gl_flags);
|
||||||
sdp->sd_rindex_vn = ip->i_gl->gl_vn - 1;
|
sdp->sd_rindex_vn = ip->i_gl->gl_vn - 1;
|
||||||
|
|
||||||
|
@ -614,14 +588,6 @@ static int init_per_node(struct gfs2_sbd *sdp, int undo)
|
||||||
goto fail_ir_i;
|
goto fail_ir_i;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(buf, "unlinked_tag%u", sdp->sd_jdesc->jd_jid);
|
|
||||||
sdp->sd_ut_inode = gfs2_lookup_simple(pn, buf);
|
|
||||||
if (IS_ERR(sdp->sd_ut_inode)) {
|
|
||||||
error = PTR_ERR(sdp->sd_ut_inode);
|
|
||||||
fs_err(sdp, "can't find local \"ut\" file: %d\n", error);
|
|
||||||
goto fail_sc_i;
|
|
||||||
}
|
|
||||||
|
|
||||||
sprintf(buf, "quota_change%u", sdp->sd_jdesc->jd_jid);
|
sprintf(buf, "quota_change%u", sdp->sd_jdesc->jd_jid);
|
||||||
sdp->sd_qc_inode = gfs2_lookup_simple(pn, buf);
|
sdp->sd_qc_inode = gfs2_lookup_simple(pn, buf);
|
||||||
if (IS_ERR(sdp->sd_qc_inode)) {
|
if (IS_ERR(sdp->sd_qc_inode)) {
|
||||||
|
@ -633,7 +599,7 @@ static int init_per_node(struct gfs2_sbd *sdp, int undo)
|
||||||
iput(pn);
|
iput(pn);
|
||||||
pn = NULL;
|
pn = NULL;
|
||||||
|
|
||||||
ip = sdp->sd_ir_inode->u.generic_ip;
|
ip = GFS2_I(sdp->sd_ir_inode);
|
||||||
error = gfs2_glock_nq_init(ip->i_gl,
|
error = gfs2_glock_nq_init(ip->i_gl,
|
||||||
LM_ST_EXCLUSIVE, 0,
|
LM_ST_EXCLUSIVE, 0,
|
||||||
&sdp->sd_ir_gh);
|
&sdp->sd_ir_gh);
|
||||||
|
@ -642,7 +608,7 @@ static int init_per_node(struct gfs2_sbd *sdp, int undo)
|
||||||
goto fail_qc_i;
|
goto fail_qc_i;
|
||||||
}
|
}
|
||||||
|
|
||||||
ip = sdp->sd_sc_inode->u.generic_ip;
|
ip = GFS2_I(sdp->sd_sc_inode);
|
||||||
error = gfs2_glock_nq_init(ip->i_gl,
|
error = gfs2_glock_nq_init(ip->i_gl,
|
||||||
LM_ST_EXCLUSIVE, 0,
|
LM_ST_EXCLUSIVE, 0,
|
||||||
&sdp->sd_sc_gh);
|
&sdp->sd_sc_gh);
|
||||||
|
@ -651,16 +617,7 @@ static int init_per_node(struct gfs2_sbd *sdp, int undo)
|
||||||
goto fail_ir_gh;
|
goto fail_ir_gh;
|
||||||
}
|
}
|
||||||
|
|
||||||
ip = sdp->sd_ut_inode->u.generic_ip;
|
ip = GFS2_I(sdp->sd_qc_inode);
|
||||||
error = gfs2_glock_nq_init(ip->i_gl,
|
|
||||||
LM_ST_EXCLUSIVE, 0,
|
|
||||||
&sdp->sd_ut_gh);
|
|
||||||
if (error) {
|
|
||||||
fs_err(sdp, "can't lock local \"ut\" file: %d\n", error);
|
|
||||||
goto fail_sc_gh;
|
|
||||||
}
|
|
||||||
|
|
||||||
ip = sdp->sd_qc_inode->u.generic_ip;
|
|
||||||
error = gfs2_glock_nq_init(ip->i_gl,
|
error = gfs2_glock_nq_init(ip->i_gl,
|
||||||
LM_ST_EXCLUSIVE, 0,
|
LM_ST_EXCLUSIVE, 0,
|
||||||
&sdp->sd_qc_gh);
|
&sdp->sd_qc_gh);
|
||||||
|
@ -675,9 +632,7 @@ static int init_per_node(struct gfs2_sbd *sdp, int undo)
|
||||||
gfs2_glock_dq_uninit(&sdp->sd_qc_gh);
|
gfs2_glock_dq_uninit(&sdp->sd_qc_gh);
|
||||||
|
|
||||||
fail_ut_gh:
|
fail_ut_gh:
|
||||||
gfs2_glock_dq_uninit(&sdp->sd_ut_gh);
|
|
||||||
|
|
||||||
fail_sc_gh:
|
|
||||||
gfs2_glock_dq_uninit(&sdp->sd_sc_gh);
|
gfs2_glock_dq_uninit(&sdp->sd_sc_gh);
|
||||||
|
|
||||||
fail_ir_gh:
|
fail_ir_gh:
|
||||||
|
@ -687,9 +642,7 @@ static int init_per_node(struct gfs2_sbd *sdp, int undo)
|
||||||
iput(sdp->sd_qc_inode);
|
iput(sdp->sd_qc_inode);
|
||||||
|
|
||||||
fail_ut_i:
|
fail_ut_i:
|
||||||
iput(sdp->sd_ut_inode);
|
|
||||||
|
|
||||||
fail_sc_i:
|
|
||||||
iput(sdp->sd_sc_inode);
|
iput(sdp->sd_sc_inode);
|
||||||
|
|
||||||
fail_ir_i:
|
fail_ir_i:
|
||||||
|
@ -707,7 +660,7 @@ static int init_threads(struct gfs2_sbd *sdp, int undo)
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
if (undo)
|
if (undo)
|
||||||
goto fail_inoded;
|
goto fail_quotad;
|
||||||
|
|
||||||
sdp->sd_log_flush_time = jiffies;
|
sdp->sd_log_flush_time = jiffies;
|
||||||
sdp->sd_jindex_refresh_time = jiffies;
|
sdp->sd_jindex_refresh_time = jiffies;
|
||||||
|
@ -731,25 +684,13 @@ static int init_threads(struct gfs2_sbd *sdp, int undo)
|
||||||
}
|
}
|
||||||
sdp->sd_quotad_process = p;
|
sdp->sd_quotad_process = p;
|
||||||
|
|
||||||
p = kthread_run(gfs2_inoded, sdp, "gfs2_inoded");
|
|
||||||
error = IS_ERR(p);
|
|
||||||
if (error) {
|
|
||||||
fs_err(sdp, "can't start inoded thread: %d\n", error);
|
|
||||||
goto fail_quotad;
|
|
||||||
}
|
|
||||||
sdp->sd_inoded_process = p;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail_inoded:
|
|
||||||
kthread_stop(sdp->sd_inoded_process);
|
|
||||||
|
|
||||||
fail_quotad:
|
fail_quotad:
|
||||||
kthread_stop(sdp->sd_quotad_process);
|
kthread_stop(sdp->sd_quotad_process);
|
||||||
|
fail:
|
||||||
fail:
|
|
||||||
kthread_stop(sdp->sd_logd_process);
|
kthread_stop(sdp->sd_logd_process);
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,6 @@
|
||||||
#include "quota.h"
|
#include "quota.h"
|
||||||
#include "rgrp.h"
|
#include "rgrp.h"
|
||||||
#include "trans.h"
|
#include "trans.h"
|
||||||
#include "unlinked.h"
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -53,8 +52,8 @@
|
||||||
static int gfs2_create(struct inode *dir, struct dentry *dentry,
|
static int gfs2_create(struct inode *dir, struct dentry *dentry,
|
||||||
int mode, struct nameidata *nd)
|
int mode, struct nameidata *nd)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *dip = dir->u.generic_ip;
|
struct gfs2_inode *dip = GFS2_I(dir);
|
||||||
struct gfs2_sbd *sdp = dip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(dir);
|
||||||
struct gfs2_holder ghs[2];
|
struct gfs2_holder ghs[2];
|
||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
int new = 1;
|
int new = 1;
|
||||||
|
@ -141,10 +140,10 @@ static struct dentry *gfs2_lookup(struct inode *dir, struct dentry *dentry,
|
||||||
static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
|
static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
|
||||||
struct dentry *dentry)
|
struct dentry *dentry)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *dip = dir->u.generic_ip;
|
struct gfs2_inode *dip = GFS2_I(dir);
|
||||||
struct gfs2_sbd *sdp = dip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(dir);
|
||||||
struct inode *inode = old_dentry->d_inode;
|
struct inode *inode = old_dentry->d_inode;
|
||||||
struct gfs2_inode *ip = inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(inode);
|
||||||
struct gfs2_holder ghs[2];
|
struct gfs2_holder ghs[2];
|
||||||
int alloc_required;
|
int alloc_required;
|
||||||
int error;
|
int error;
|
||||||
|
@ -231,30 +230,29 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
|
||||||
|
|
||||||
error = gfs2_change_nlink(ip, +1);
|
error = gfs2_change_nlink(ip, +1);
|
||||||
|
|
||||||
out_end_trans:
|
out_end_trans:
|
||||||
gfs2_trans_end(sdp);
|
gfs2_trans_end(sdp);
|
||||||
|
|
||||||
out_ipres:
|
out_ipres:
|
||||||
if (alloc_required)
|
if (alloc_required)
|
||||||
gfs2_inplace_release(dip);
|
gfs2_inplace_release(dip);
|
||||||
|
|
||||||
out_gunlock_q:
|
out_gunlock_q:
|
||||||
if (alloc_required)
|
if (alloc_required)
|
||||||
gfs2_quota_unlock(dip);
|
gfs2_quota_unlock(dip);
|
||||||
|
|
||||||
out_alloc:
|
out_alloc:
|
||||||
if (alloc_required)
|
if (alloc_required)
|
||||||
gfs2_alloc_put(dip);
|
gfs2_alloc_put(dip);
|
||||||
|
|
||||||
out_gunlock:
|
out_gunlock:
|
||||||
gfs2_glock_dq_m(2, ghs);
|
gfs2_glock_dq_m(2, ghs);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
gfs2_holder_uninit(ghs);
|
gfs2_holder_uninit(ghs);
|
||||||
gfs2_holder_uninit(ghs + 1);
|
gfs2_holder_uninit(ghs + 1);
|
||||||
|
|
||||||
if (!error) {
|
if (!error) {
|
||||||
atomic_inc(&inode->i_count);
|
|
||||||
d_instantiate(dentry, inode);
|
d_instantiate(dentry, inode);
|
||||||
mark_inode_dirty(inode);
|
mark_inode_dirty(inode);
|
||||||
}
|
}
|
||||||
|
@ -274,17 +272,12 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
|
||||||
|
|
||||||
static int gfs2_unlink(struct inode *dir, struct dentry *dentry)
|
static int gfs2_unlink(struct inode *dir, struct dentry *dentry)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *dip = dir->u.generic_ip;
|
struct gfs2_inode *dip = GFS2_I(dir);
|
||||||
struct gfs2_sbd *sdp = dip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(dir);
|
||||||
struct gfs2_inode *ip = dentry->d_inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(dentry->d_inode);
|
||||||
struct gfs2_unlinked *ul;
|
|
||||||
struct gfs2_holder ghs[2];
|
struct gfs2_holder ghs[2];
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
error = gfs2_unlinked_get(sdp, &ul);
|
|
||||||
if (error)
|
|
||||||
return error;
|
|
||||||
|
|
||||||
gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs);
|
gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs);
|
||||||
gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1);
|
gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1);
|
||||||
|
|
||||||
|
@ -296,24 +289,23 @@ static int gfs2_unlink(struct inode *dir, struct dentry *dentry)
|
||||||
if (error)
|
if (error)
|
||||||
goto out_gunlock;
|
goto out_gunlock;
|
||||||
|
|
||||||
error = gfs2_trans_begin(sdp, 2 * RES_DINODE + RES_LEAF +
|
error = gfs2_trans_begin(sdp, 2*RES_DINODE + RES_LEAF + RES_RG_BIT, 0);
|
||||||
RES_UNLINKED, 0);
|
|
||||||
if (error)
|
if (error)
|
||||||
goto out_gunlock;
|
goto out_gunlock;
|
||||||
|
|
||||||
error = gfs2_unlinki(dip, &dentry->d_name, ip, ul);
|
error = gfs2_dir_del(dip, &dentry->d_name);
|
||||||
|
if (error)
|
||||||
|
goto out_end_trans;
|
||||||
|
|
||||||
|
error = gfs2_change_nlink(ip, -1);
|
||||||
|
|
||||||
|
out_end_trans:
|
||||||
gfs2_trans_end(sdp);
|
gfs2_trans_end(sdp);
|
||||||
|
out_gunlock:
|
||||||
out_gunlock:
|
|
||||||
gfs2_glock_dq_m(2, ghs);
|
gfs2_glock_dq_m(2, ghs);
|
||||||
|
out:
|
||||||
out:
|
|
||||||
gfs2_holder_uninit(ghs);
|
gfs2_holder_uninit(ghs);
|
||||||
gfs2_holder_uninit(ghs + 1);
|
gfs2_holder_uninit(ghs + 1);
|
||||||
|
|
||||||
gfs2_unlinked_put(sdp, ul);
|
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -329,8 +321,8 @@ static int gfs2_unlink(struct inode *dir, struct dentry *dentry)
|
||||||
static int gfs2_symlink(struct inode *dir, struct dentry *dentry,
|
static int gfs2_symlink(struct inode *dir, struct dentry *dentry,
|
||||||
const char *symname)
|
const char *symname)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *dip = dir->u.generic_ip, *ip;
|
struct gfs2_inode *dip = GFS2_I(dir), *ip;
|
||||||
struct gfs2_sbd *sdp = dip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(dir);
|
||||||
struct gfs2_holder ghs[2];
|
struct gfs2_holder ghs[2];
|
||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
struct buffer_head *dibh;
|
struct buffer_head *dibh;
|
||||||
|
@ -388,8 +380,8 @@ static int gfs2_symlink(struct inode *dir, struct dentry *dentry,
|
||||||
|
|
||||||
static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode)
|
static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *dip = dir->u.generic_ip, *ip;
|
struct gfs2_inode *dip = GFS2_I(dir), *ip;
|
||||||
struct gfs2_sbd *sdp = dip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(dir);
|
||||||
struct gfs2_holder ghs[2];
|
struct gfs2_holder ghs[2];
|
||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
struct buffer_head *dibh;
|
struct buffer_head *dibh;
|
||||||
|
@ -466,17 +458,12 @@ static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode)
|
||||||
|
|
||||||
static int gfs2_rmdir(struct inode *dir, struct dentry *dentry)
|
static int gfs2_rmdir(struct inode *dir, struct dentry *dentry)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *dip = dir->u.generic_ip;
|
struct gfs2_inode *dip = GFS2_I(dir);
|
||||||
struct gfs2_sbd *sdp = dip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(dir);
|
||||||
struct gfs2_inode *ip = dentry->d_inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(dentry->d_inode);
|
||||||
struct gfs2_unlinked *ul;
|
|
||||||
struct gfs2_holder ghs[2];
|
struct gfs2_holder ghs[2];
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
error = gfs2_unlinked_get(sdp, &ul);
|
|
||||||
if (error)
|
|
||||||
return error;
|
|
||||||
|
|
||||||
gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs);
|
gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs);
|
||||||
gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1);
|
gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1);
|
||||||
|
|
||||||
|
@ -499,12 +486,11 @@ static int gfs2_rmdir(struct inode *dir, struct dentry *dentry)
|
||||||
goto out_gunlock;
|
goto out_gunlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = gfs2_trans_begin(sdp, 2 * RES_DINODE + 3 * RES_LEAF +
|
error = gfs2_trans_begin(sdp, 2 * RES_DINODE + 3 * RES_LEAF + RES_RG_BIT, 0);
|
||||||
RES_UNLINKED, 0);
|
|
||||||
if (error)
|
if (error)
|
||||||
goto out_gunlock;
|
goto out_gunlock;
|
||||||
|
|
||||||
error = gfs2_rmdiri(dip, &dentry->d_name, ip, ul);
|
error = gfs2_rmdiri(dip, &dentry->d_name, ip);
|
||||||
|
|
||||||
gfs2_trans_end(sdp);
|
gfs2_trans_end(sdp);
|
||||||
|
|
||||||
|
@ -515,8 +501,6 @@ static int gfs2_rmdir(struct inode *dir, struct dentry *dentry)
|
||||||
gfs2_holder_uninit(ghs);
|
gfs2_holder_uninit(ghs);
|
||||||
gfs2_holder_uninit(ghs + 1);
|
gfs2_holder_uninit(ghs + 1);
|
||||||
|
|
||||||
gfs2_unlinked_put(sdp, ul);
|
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -532,8 +516,8 @@ static int gfs2_rmdir(struct inode *dir, struct dentry *dentry)
|
||||||
static int gfs2_mknod(struct inode *dir, struct dentry *dentry, int mode,
|
static int gfs2_mknod(struct inode *dir, struct dentry *dentry, int mode,
|
||||||
dev_t dev)
|
dev_t dev)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *dip = dir->u.generic_ip, *ip;
|
struct gfs2_inode *dip = GFS2_I(dir), *ip;
|
||||||
struct gfs2_sbd *sdp = dip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(dir);
|
||||||
struct gfs2_holder ghs[2];
|
struct gfs2_holder ghs[2];
|
||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
struct buffer_head *dibh;
|
struct buffer_head *dibh;
|
||||||
|
@ -600,12 +584,11 @@ static int gfs2_mknod(struct inode *dir, struct dentry *dentry, int mode,
|
||||||
static int gfs2_rename(struct inode *odir, struct dentry *odentry,
|
static int gfs2_rename(struct inode *odir, struct dentry *odentry,
|
||||||
struct inode *ndir, struct dentry *ndentry)
|
struct inode *ndir, struct dentry *ndentry)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *odip = odir->u.generic_ip;
|
struct gfs2_inode *odip = GFS2_I(odir);
|
||||||
struct gfs2_inode *ndip = ndir->u.generic_ip;
|
struct gfs2_inode *ndip = GFS2_I(ndir);
|
||||||
struct gfs2_inode *ip = odentry->d_inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(odentry->d_inode);
|
||||||
struct gfs2_inode *nip = NULL;
|
struct gfs2_inode *nip = NULL;
|
||||||
struct gfs2_sbd *sdp = odip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(odir);
|
||||||
struct gfs2_unlinked *ul;
|
|
||||||
struct gfs2_holder ghs[4], r_gh;
|
struct gfs2_holder ghs[4], r_gh;
|
||||||
unsigned int num_gh;
|
unsigned int num_gh;
|
||||||
int dir_rename = 0;
|
int dir_rename = 0;
|
||||||
|
@ -614,15 +597,11 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
if (ndentry->d_inode) {
|
if (ndentry->d_inode) {
|
||||||
nip = ndentry->d_inode->u.generic_ip;
|
nip = GFS2_I(ndentry->d_inode);
|
||||||
if (ip == nip)
|
if (ip == nip)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = gfs2_unlinked_get(sdp, &ul);
|
|
||||||
if (error)
|
|
||||||
return error;
|
|
||||||
|
|
||||||
/* Make sure we aren't trying to move a dirctory into it's subdir */
|
/* Make sure we aren't trying to move a dirctory into it's subdir */
|
||||||
|
|
||||||
if (S_ISDIR(ip->i_di.di_mode) && odip != ndip) {
|
if (S_ISDIR(ip->i_di.di_mode) && odip != ndip) {
|
||||||
|
@ -743,14 +722,12 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
|
||||||
error = gfs2_trans_begin(sdp, sdp->sd_max_dirres +
|
error = gfs2_trans_begin(sdp, sdp->sd_max_dirres +
|
||||||
al->al_rgd->rd_ri.ri_length +
|
al->al_rgd->rd_ri.ri_length +
|
||||||
4 * RES_DINODE + 4 * RES_LEAF +
|
4 * RES_DINODE + 4 * RES_LEAF +
|
||||||
RES_UNLINKED + RES_STATFS +
|
RES_STATFS + RES_QUOTA, 0);
|
||||||
RES_QUOTA, 0);
|
|
||||||
if (error)
|
if (error)
|
||||||
goto out_ipreserv;
|
goto out_ipreserv;
|
||||||
} else {
|
} else {
|
||||||
error = gfs2_trans_begin(sdp, 4 * RES_DINODE +
|
error = gfs2_trans_begin(sdp, 4 * RES_DINODE +
|
||||||
5 * RES_LEAF +
|
5 * RES_LEAF, 0);
|
||||||
RES_UNLINKED, 0);
|
|
||||||
if (error)
|
if (error)
|
||||||
goto out_gunlock;
|
goto out_gunlock;
|
||||||
}
|
}
|
||||||
|
@ -759,9 +736,13 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
|
||||||
|
|
||||||
if (nip) {
|
if (nip) {
|
||||||
if (S_ISDIR(nip->i_di.di_mode))
|
if (S_ISDIR(nip->i_di.di_mode))
|
||||||
error = gfs2_rmdiri(ndip, &ndentry->d_name, nip, ul);
|
error = gfs2_rmdiri(ndip, &ndentry->d_name, nip);
|
||||||
else
|
else {
|
||||||
error = gfs2_unlinki(ndip, &ndentry->d_name, nip, ul);
|
error = gfs2_dir_del(ndip, &ndentry->d_name);
|
||||||
|
if (error)
|
||||||
|
goto out_end_trans;
|
||||||
|
error = gfs2_change_nlink(nip, -1);
|
||||||
|
}
|
||||||
if (error)
|
if (error)
|
||||||
goto out_end_trans;
|
goto out_end_trans;
|
||||||
}
|
}
|
||||||
|
@ -800,35 +781,26 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
|
||||||
if (error)
|
if (error)
|
||||||
goto out_end_trans;
|
goto out_end_trans;
|
||||||
|
|
||||||
out_end_trans:
|
out_end_trans:
|
||||||
gfs2_trans_end(sdp);
|
gfs2_trans_end(sdp);
|
||||||
|
out_ipreserv:
|
||||||
out_ipreserv:
|
|
||||||
if (alloc_required)
|
if (alloc_required)
|
||||||
gfs2_inplace_release(ndip);
|
gfs2_inplace_release(ndip);
|
||||||
|
out_gunlock_q:
|
||||||
out_gunlock_q:
|
|
||||||
if (alloc_required)
|
if (alloc_required)
|
||||||
gfs2_quota_unlock(ndip);
|
gfs2_quota_unlock(ndip);
|
||||||
|
out_alloc:
|
||||||
out_alloc:
|
|
||||||
if (alloc_required)
|
if (alloc_required)
|
||||||
gfs2_alloc_put(ndip);
|
gfs2_alloc_put(ndip);
|
||||||
|
out_gunlock:
|
||||||
out_gunlock:
|
|
||||||
gfs2_glock_dq_m(num_gh, ghs);
|
gfs2_glock_dq_m(num_gh, ghs);
|
||||||
|
out_uninit:
|
||||||
out_uninit:
|
|
||||||
for (x = 0; x < num_gh; x++)
|
for (x = 0; x < num_gh; x++)
|
||||||
gfs2_holder_uninit(ghs + x);
|
gfs2_holder_uninit(ghs + x);
|
||||||
|
out_gunlock_r:
|
||||||
out_gunlock_r:
|
|
||||||
if (dir_rename)
|
if (dir_rename)
|
||||||
gfs2_glock_dq_uninit(&r_gh);
|
gfs2_glock_dq_uninit(&r_gh);
|
||||||
|
out:
|
||||||
out:
|
|
||||||
gfs2_unlinked_put(sdp, ul);
|
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -844,7 +816,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
|
||||||
static int gfs2_readlink(struct dentry *dentry, char __user *user_buf,
|
static int gfs2_readlink(struct dentry *dentry, char __user *user_buf,
|
||||||
int user_size)
|
int user_size)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = dentry->d_inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(dentry->d_inode);
|
||||||
char array[GFS2_FAST_NAME_SIZE], *buf = array;
|
char array[GFS2_FAST_NAME_SIZE], *buf = array;
|
||||||
unsigned int len = GFS2_FAST_NAME_SIZE;
|
unsigned int len = GFS2_FAST_NAME_SIZE;
|
||||||
int error;
|
int error;
|
||||||
|
@ -880,7 +852,7 @@ static int gfs2_readlink(struct dentry *dentry, char __user *user_buf,
|
||||||
|
|
||||||
static void *gfs2_follow_link(struct dentry *dentry, struct nameidata *nd)
|
static void *gfs2_follow_link(struct dentry *dentry, struct nameidata *nd)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = dentry->d_inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(dentry->d_inode);
|
||||||
char array[GFS2_FAST_NAME_SIZE], *buf = array;
|
char array[GFS2_FAST_NAME_SIZE], *buf = array;
|
||||||
unsigned int len = GFS2_FAST_NAME_SIZE;
|
unsigned int len = GFS2_FAST_NAME_SIZE;
|
||||||
int error;
|
int error;
|
||||||
|
@ -906,7 +878,7 @@ static void *gfs2_follow_link(struct dentry *dentry, struct nameidata *nd)
|
||||||
|
|
||||||
static int gfs2_permission(struct inode *inode, int mask, struct nameidata *nd)
|
static int gfs2_permission(struct inode *inode, int mask, struct nameidata *nd)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(inode);
|
||||||
struct gfs2_holder i_gh;
|
struct gfs2_holder i_gh;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
@ -926,7 +898,7 @@ static int gfs2_permission(struct inode *inode, int mask, struct nameidata *nd)
|
||||||
|
|
||||||
static int setattr_size(struct inode *inode, struct iattr *attr)
|
static int setattr_size(struct inode *inode, struct iattr *attr)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(inode);
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
if (attr->ia_size != ip->i_di.di_size) {
|
if (attr->ia_size != ip->i_di.di_size) {
|
||||||
|
@ -944,8 +916,8 @@ static int setattr_size(struct inode *inode, struct iattr *attr)
|
||||||
|
|
||||||
static int setattr_chown(struct inode *inode, struct iattr *attr)
|
static int setattr_chown(struct inode *inode, struct iattr *attr)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(inode);
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(inode);
|
||||||
struct buffer_head *dibh;
|
struct buffer_head *dibh;
|
||||||
uint32_t ouid, ogid, nuid, ngid;
|
uint32_t ouid, ogid, nuid, ngid;
|
||||||
int error;
|
int error;
|
||||||
|
@ -1021,7 +993,7 @@ static int setattr_chown(struct inode *inode, struct iattr *attr)
|
||||||
static int gfs2_setattr(struct dentry *dentry, struct iattr *attr)
|
static int gfs2_setattr(struct dentry *dentry, struct iattr *attr)
|
||||||
{
|
{
|
||||||
struct inode *inode = dentry->d_inode;
|
struct inode *inode = dentry->d_inode;
|
||||||
struct gfs2_inode *ip = inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(inode);
|
||||||
struct gfs2_holder i_gh;
|
struct gfs2_holder i_gh;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
@ -1068,7 +1040,7 @@ static int gfs2_getattr(struct vfsmount *mnt, struct dentry *dentry,
|
||||||
struct kstat *stat)
|
struct kstat *stat)
|
||||||
{
|
{
|
||||||
struct inode *inode = dentry->d_inode;
|
struct inode *inode = dentry->d_inode;
|
||||||
struct gfs2_inode *ip = inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(inode);
|
||||||
struct gfs2_holder gh;
|
struct gfs2_holder gh;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
@ -1084,7 +1056,7 @@ static int gfs2_getattr(struct vfsmount *mnt, struct dentry *dentry,
|
||||||
static int gfs2_setxattr(struct dentry *dentry, const char *name,
|
static int gfs2_setxattr(struct dentry *dentry, const char *name,
|
||||||
const void *data, size_t size, int flags)
|
const void *data, size_t size, int flags)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = dentry->d_inode->u.generic_ip;
|
struct inode *inode = dentry->d_inode;
|
||||||
struct gfs2_ea_request er;
|
struct gfs2_ea_request er;
|
||||||
|
|
||||||
memset(&er, 0, sizeof(struct gfs2_ea_request));
|
memset(&er, 0, sizeof(struct gfs2_ea_request));
|
||||||
|
@ -1096,9 +1068,9 @@ static int gfs2_setxattr(struct dentry *dentry, const char *name,
|
||||||
er.er_data_len = size;
|
er.er_data_len = size;
|
||||||
er.er_flags = flags;
|
er.er_flags = flags;
|
||||||
|
|
||||||
gfs2_assert_warn(ip->i_sbd, !(er.er_flags & GFS2_ERF_MODE));
|
gfs2_assert_warn(GFS2_SB(inode), !(er.er_flags & GFS2_ERF_MODE));
|
||||||
|
|
||||||
return gfs2_ea_set(ip, &er);
|
return gfs2_ea_set(GFS2_I(inode), &er);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t gfs2_getxattr(struct dentry *dentry, const char *name,
|
static ssize_t gfs2_getxattr(struct dentry *dentry, const char *name,
|
||||||
|
@ -1114,7 +1086,7 @@ static ssize_t gfs2_getxattr(struct dentry *dentry, const char *name,
|
||||||
er.er_name_len = strlen(er.er_name);
|
er.er_name_len = strlen(er.er_name);
|
||||||
er.er_data_len = size;
|
er.er_data_len = size;
|
||||||
|
|
||||||
return gfs2_ea_get(dentry->d_inode->u.generic_ip, &er);
|
return gfs2_ea_get(GFS2_I(dentry->d_inode), &er);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t gfs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
|
static ssize_t gfs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
|
||||||
|
@ -1125,7 +1097,7 @@ static ssize_t gfs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
|
||||||
er.er_data = (size) ? buffer : NULL;
|
er.er_data = (size) ? buffer : NULL;
|
||||||
er.er_data_len = size;
|
er.er_data_len = size;
|
||||||
|
|
||||||
return gfs2_ea_list(dentry->d_inode->u.generic_ip, &er);
|
return gfs2_ea_list(GFS2_I(dentry->d_inode), &er);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gfs2_removexattr(struct dentry *dentry, const char *name)
|
static int gfs2_removexattr(struct dentry *dentry, const char *name)
|
||||||
|
@ -1138,7 +1110,7 @@ static int gfs2_removexattr(struct dentry *dentry, const char *name)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
er.er_name_len = strlen(er.er_name);
|
er.er_name_len = strlen(er.er_name);
|
||||||
|
|
||||||
return gfs2_ea_remove(dentry->d_inode->u.generic_ip, &er);
|
return gfs2_ea_remove(GFS2_I(dentry->d_inode), &er);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct inode_operations gfs2_file_iops = {
|
struct inode_operations gfs2_file_iops = {
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include <linux/kthread.h>
|
#include <linux/kthread.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/gfs2_ondisk.h>
|
#include <linux/gfs2_ondisk.h>
|
||||||
|
#include <linux/crc32.h>
|
||||||
|
|
||||||
#include "gfs2.h"
|
#include "gfs2.h"
|
||||||
#include "lm_interface.h"
|
#include "lm_interface.h"
|
||||||
|
@ -36,6 +37,10 @@
|
||||||
#include "super.h"
|
#include "super.h"
|
||||||
#include "sys.h"
|
#include "sys.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "trans.h"
|
||||||
|
#include "dir.h"
|
||||||
|
#include "eattr.h"
|
||||||
|
#include "bmap.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gfs2_write_inode - Make sure the inode is stable on the disk
|
* gfs2_write_inode - Make sure the inode is stable on the disk
|
||||||
|
@ -47,12 +52,15 @@
|
||||||
|
|
||||||
static int gfs2_write_inode(struct inode *inode, int sync)
|
static int gfs2_write_inode(struct inode *inode, int sync)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(inode);
|
||||||
|
|
||||||
if (current->flags & PF_MEMALLOC)
|
/* Check this is a "normal" inode */
|
||||||
return 0;
|
if (inode->u.generic_ip) {
|
||||||
if (ip && sync)
|
if (current->flags & PF_MEMALLOC)
|
||||||
gfs2_log_flush(ip->i_gl->gl_sbd, ip->i_gl);
|
return 0;
|
||||||
|
if (sync)
|
||||||
|
gfs2_log_flush(ip->i_gl->gl_sbd, ip->i_gl);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -78,7 +86,6 @@ static void gfs2_put_super(struct super_block *sb)
|
||||||
gfs2_glock_dq_uninit(&sdp->sd_freeze_gh);
|
gfs2_glock_dq_uninit(&sdp->sd_freeze_gh);
|
||||||
mutex_unlock(&sdp->sd_freeze_lock);
|
mutex_unlock(&sdp->sd_freeze_lock);
|
||||||
|
|
||||||
kthread_stop(sdp->sd_inoded_process);
|
|
||||||
kthread_stop(sdp->sd_quotad_process);
|
kthread_stop(sdp->sd_quotad_process);
|
||||||
kthread_stop(sdp->sd_logd_process);
|
kthread_stop(sdp->sd_logd_process);
|
||||||
kthread_stop(sdp->sd_recoverd_process);
|
kthread_stop(sdp->sd_recoverd_process);
|
||||||
|
@ -110,11 +117,9 @@ static void gfs2_put_super(struct super_block *sb)
|
||||||
gfs2_glock_dq_uninit(&sdp->sd_jinode_gh);
|
gfs2_glock_dq_uninit(&sdp->sd_jinode_gh);
|
||||||
gfs2_glock_dq_uninit(&sdp->sd_ir_gh);
|
gfs2_glock_dq_uninit(&sdp->sd_ir_gh);
|
||||||
gfs2_glock_dq_uninit(&sdp->sd_sc_gh);
|
gfs2_glock_dq_uninit(&sdp->sd_sc_gh);
|
||||||
gfs2_glock_dq_uninit(&sdp->sd_ut_gh);
|
|
||||||
gfs2_glock_dq_uninit(&sdp->sd_qc_gh);
|
gfs2_glock_dq_uninit(&sdp->sd_qc_gh);
|
||||||
iput(sdp->sd_ir_inode);
|
iput(sdp->sd_ir_inode);
|
||||||
iput(sdp->sd_sc_inode);
|
iput(sdp->sd_sc_inode);
|
||||||
iput(sdp->sd_ut_inode);
|
|
||||||
iput(sdp->sd_qc_inode);
|
iput(sdp->sd_qc_inode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,16 +279,20 @@ static int gfs2_remount_fs(struct super_block *sb, int *flags, char *data)
|
||||||
|
|
||||||
static void gfs2_clear_inode(struct inode *inode)
|
static void gfs2_clear_inode(struct inode *inode)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = inode->u.generic_ip;
|
/* This tells us its a "real" inode and not one which only
|
||||||
|
* serves to contain an address space (see rgrp.c, meta_io.c)
|
||||||
if (ip) {
|
* which therefore doesn't have its own glocks.
|
||||||
spin_lock(&ip->i_spin);
|
*/
|
||||||
ip->i_vnode = NULL;
|
if (inode->u.generic_ip) {
|
||||||
inode->u.generic_ip = NULL;
|
struct gfs2_inode *ip = GFS2_I(inode);
|
||||||
spin_unlock(&ip->i_spin);
|
gfs2_glock_inode_squish(inode);
|
||||||
|
gfs2_assert(inode->i_sb->s_fs_info, ip->i_gl->gl_state == LM_ST_UNLOCKED);
|
||||||
|
ip->i_gl->gl_object = NULL;
|
||||||
gfs2_glock_schedule_for_reclaim(ip->i_gl);
|
gfs2_glock_schedule_for_reclaim(ip->i_gl);
|
||||||
gfs2_inode_put(ip);
|
gfs2_glock_put(ip->i_gl);
|
||||||
|
ip->i_gl = NULL;
|
||||||
|
if (ip->i_iopen_gh.gh_gl)
|
||||||
|
gfs2_glock_dq_uninit(&ip->i_iopen_gh);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -361,6 +370,70 @@ static int gfs2_show_options(struct seq_file *s, struct vfsmount *mnt)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We have to (at the moment) hold the inodes main lock to cover
|
||||||
|
* the gap between unlocking the shared lock on the iopen lock and
|
||||||
|
* taking the exclusive lock. I'd rather do a shared -> exclusive
|
||||||
|
* conversion on the iopen lock, but we can change that later. This
|
||||||
|
* is safe, just less efficient.
|
||||||
|
*/
|
||||||
|
static void gfs2_delete_inode(struct inode *inode)
|
||||||
|
{
|
||||||
|
struct gfs2_sbd *sdp = inode->i_sb->s_fs_info;
|
||||||
|
struct gfs2_inode *ip = GFS2_I(inode);
|
||||||
|
struct gfs2_holder gh;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
if (!inode->u.generic_ip)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB | GL_NOCACHE, &gh);
|
||||||
|
if (unlikely(error)) {
|
||||||
|
gfs2_glock_dq_uninit(&ip->i_iopen_gh);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
gfs2_glock_dq(&ip->i_iopen_gh);
|
||||||
|
gfs2_holder_reinit(LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB | GL_NOCACHE, &ip->i_iopen_gh);
|
||||||
|
error = gfs2_glock_nq(&ip->i_iopen_gh);
|
||||||
|
if (error)
|
||||||
|
goto out_uninit;
|
||||||
|
|
||||||
|
if (S_ISDIR(ip->i_di.di_mode) &&
|
||||||
|
(ip->i_di.di_flags & GFS2_DIF_EXHASH)) {
|
||||||
|
error = gfs2_dir_exhash_dealloc(ip);
|
||||||
|
if (error)
|
||||||
|
goto out_unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ip->i_di.di_eattr) {
|
||||||
|
error = gfs2_ea_dealloc(ip);
|
||||||
|
if (error)
|
||||||
|
goto out_unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gfs2_is_stuffed(ip)) {
|
||||||
|
error = gfs2_file_dealloc(ip);
|
||||||
|
if (error)
|
||||||
|
goto out_unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = gfs2_dinode_dealloc(ip);
|
||||||
|
|
||||||
|
out_unlock:
|
||||||
|
gfs2_glock_dq(&ip->i_iopen_gh);
|
||||||
|
out_uninit:
|
||||||
|
gfs2_holder_uninit(&ip->i_iopen_gh);
|
||||||
|
gfs2_glock_dq_uninit(&gh);
|
||||||
|
if (error)
|
||||||
|
fs_warn(sdp, "gfs2_delete_inode: %d\n", error);
|
||||||
|
out:
|
||||||
|
truncate_inode_pages(&inode->i_data, 0);
|
||||||
|
clear_inode(inode);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static struct inode *gfs2_alloc_inode(struct super_block *sb)
|
static struct inode *gfs2_alloc_inode(struct super_block *sb)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = sb->s_fs_info;
|
struct gfs2_sbd *sdp = sb->s_fs_info;
|
||||||
|
@ -370,8 +443,6 @@ static struct inode *gfs2_alloc_inode(struct super_block *sb)
|
||||||
if (ip) {
|
if (ip) {
|
||||||
ip->i_flags = 0;
|
ip->i_flags = 0;
|
||||||
ip->i_gl = NULL;
|
ip->i_gl = NULL;
|
||||||
ip->i_sbd = sdp;
|
|
||||||
ip->i_vnode = &ip->i_inode;
|
|
||||||
ip->i_greedy = gfs2_tune_get(sdp, gt_greedy_default);
|
ip->i_greedy = gfs2_tune_get(sdp, gt_greedy_default);
|
||||||
ip->i_last_pfault = jiffies;
|
ip->i_last_pfault = jiffies;
|
||||||
}
|
}
|
||||||
|
@ -387,6 +458,7 @@ struct super_operations gfs2_super_ops = {
|
||||||
.alloc_inode = gfs2_alloc_inode,
|
.alloc_inode = gfs2_alloc_inode,
|
||||||
.destroy_inode = gfs2_destroy_inode,
|
.destroy_inode = gfs2_destroy_inode,
|
||||||
.write_inode = gfs2_write_inode,
|
.write_inode = gfs2_write_inode,
|
||||||
|
.delete_inode = gfs2_delete_inode,
|
||||||
.put_super = gfs2_put_super,
|
.put_super = gfs2_put_super,
|
||||||
.write_super = gfs2_write_super,
|
.write_super = gfs2_write_super,
|
||||||
.write_super_lockfs = gfs2_write_super_lockfs,
|
.write_super_lockfs = gfs2_write_super_lockfs,
|
||||||
|
|
|
@ -38,15 +38,15 @@ static void pfault_be_greedy(struct gfs2_inode *ip)
|
||||||
ip->i_last_pfault = jiffies;
|
ip->i_last_pfault = jiffies;
|
||||||
spin_unlock(&ip->i_spin);
|
spin_unlock(&ip->i_spin);
|
||||||
|
|
||||||
gfs2_inode_hold(ip);
|
igrab(&ip->i_inode);
|
||||||
if (gfs2_glock_be_greedy(ip->i_gl, time))
|
if (gfs2_glock_be_greedy(ip->i_gl, time))
|
||||||
gfs2_inode_put(ip);
|
iput(&ip->i_inode);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct page *gfs2_private_nopage(struct vm_area_struct *area,
|
static struct page *gfs2_private_nopage(struct vm_area_struct *area,
|
||||||
unsigned long address, int *type)
|
unsigned long address, int *type)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = area->vm_file->f_mapping->host->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(area->vm_file->f_mapping->host);
|
||||||
struct gfs2_holder i_gh;
|
struct gfs2_holder i_gh;
|
||||||
struct page *result;
|
struct page *result;
|
||||||
int error;
|
int error;
|
||||||
|
@ -69,7 +69,7 @@ static struct page *gfs2_private_nopage(struct vm_area_struct *area,
|
||||||
|
|
||||||
static int alloc_page_backing(struct gfs2_inode *ip, struct page *page)
|
static int alloc_page_backing(struct gfs2_inode *ip, struct page *page)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
||||||
unsigned long index = page->index;
|
unsigned long index = page->index;
|
||||||
uint64_t lblock = index << (PAGE_CACHE_SHIFT -
|
uint64_t lblock = index << (PAGE_CACHE_SHIFT -
|
||||||
sdp->sd_sb.sb_bsize_shift);
|
sdp->sd_sb.sb_bsize_shift);
|
||||||
|
@ -114,7 +114,7 @@ static int alloc_page_backing(struct gfs2_inode *ip, struct page *page)
|
||||||
unsigned int extlen;
|
unsigned int extlen;
|
||||||
int new = 1;
|
int new = 1;
|
||||||
|
|
||||||
error = gfs2_extent_map(ip->i_vnode, lblock, &new, &dblock, &extlen);
|
error = gfs2_extent_map(&ip->i_inode, lblock, &new, &dblock, &extlen);
|
||||||
if (error)
|
if (error)
|
||||||
goto out_trans;
|
goto out_trans;
|
||||||
|
|
||||||
|
@ -142,7 +142,7 @@ static int alloc_page_backing(struct gfs2_inode *ip, struct page *page)
|
||||||
static struct page *gfs2_sharewrite_nopage(struct vm_area_struct *area,
|
static struct page *gfs2_sharewrite_nopage(struct vm_area_struct *area,
|
||||||
unsigned long address, int *type)
|
unsigned long address, int *type)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = area->vm_file->f_mapping->host->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(area->vm_file->f_mapping->host);
|
||||||
struct gfs2_holder i_gh;
|
struct gfs2_holder i_gh;
|
||||||
struct page *result = NULL;
|
struct page *result = NULL;
|
||||||
unsigned long index = ((address - area->vm_start) >> PAGE_CACHE_SHIFT) +
|
unsigned long index = ((address - area->vm_start) >> PAGE_CACHE_SHIFT) +
|
||||||
|
|
|
@ -38,20 +38,17 @@ void gfs2_pte_inval(struct gfs2_glock *gl)
|
||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
|
|
||||||
ip = gl->gl_object;
|
ip = gl->gl_object;
|
||||||
|
inode = &ip->i_inode;
|
||||||
if (!ip || !S_ISREG(ip->i_di.di_mode))
|
if (!ip || !S_ISREG(ip->i_di.di_mode))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!test_bit(GIF_PAGED, &ip->i_flags))
|
if (!test_bit(GIF_PAGED, &ip->i_flags))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
inode = gfs2_ip2v_lookup(ip);
|
unmap_shared_mapping_range(inode->i_mapping, 0, 0);
|
||||||
if (inode) {
|
|
||||||
unmap_shared_mapping_range(inode->i_mapping, 0, 0);
|
|
||||||
iput(inode);
|
|
||||||
|
|
||||||
if (test_bit(GIF_SW_PAGED, &ip->i_flags))
|
if (test_bit(GIF_SW_PAGED, &ip->i_flags))
|
||||||
set_bit(GLF_DIRTY, &gl->gl_flags);
|
set_bit(GLF_DIRTY, &gl->gl_flags);
|
||||||
}
|
|
||||||
|
|
||||||
clear_bit(GIF_SW_PAGED, &ip->i_flags);
|
clear_bit(GIF_SW_PAGED, &ip->i_flags);
|
||||||
}
|
}
|
||||||
|
@ -68,19 +65,12 @@ void gfs2_page_inval(struct gfs2_glock *gl)
|
||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
|
|
||||||
ip = gl->gl_object;
|
ip = gl->gl_object;
|
||||||
|
inode = &ip->i_inode;
|
||||||
if (!ip || !S_ISREG(ip->i_di.di_mode))
|
if (!ip || !S_ISREG(ip->i_di.di_mode))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
inode = gfs2_ip2v_lookup(ip);
|
truncate_inode_pages(inode->i_mapping, 0);
|
||||||
if (inode) {
|
gfs2_assert_withdraw(GFS2_SB(&ip->i_inode), !inode->i_mapping->nrpages);
|
||||||
struct address_space *mapping = inode->i_mapping;
|
|
||||||
|
|
||||||
truncate_inode_pages(mapping, 0);
|
|
||||||
gfs2_assert_withdraw(ip->i_sbd, !mapping->nrpages);
|
|
||||||
|
|
||||||
iput(inode);
|
|
||||||
}
|
|
||||||
|
|
||||||
clear_bit(GIF_PAGED, &ip->i_flags);
|
clear_bit(GIF_PAGED, &ip->i_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,32 +87,30 @@ void gfs2_page_sync(struct gfs2_glock *gl, int flags)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip;
|
struct gfs2_inode *ip;
|
||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
|
struct address_space *mapping;
|
||||||
|
int error = 0;
|
||||||
|
|
||||||
ip = gl->gl_object;
|
ip = gl->gl_object;
|
||||||
|
inode = &ip->i_inode;
|
||||||
if (!ip || !S_ISREG(ip->i_di.di_mode))
|
if (!ip || !S_ISREG(ip->i_di.di_mode))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
inode = gfs2_ip2v_lookup(ip);
|
mapping = inode->i_mapping;
|
||||||
if (inode) {
|
|
||||||
struct address_space *mapping = inode->i_mapping;
|
|
||||||
int error = 0;
|
|
||||||
|
|
||||||
if (flags & DIO_START)
|
if (flags & DIO_START)
|
||||||
filemap_fdatawrite(mapping);
|
filemap_fdatawrite(mapping);
|
||||||
if (!error && (flags & DIO_WAIT))
|
if (!error && (flags & DIO_WAIT))
|
||||||
error = filemap_fdatawait(mapping);
|
error = filemap_fdatawait(mapping);
|
||||||
|
|
||||||
/* Put back any errors cleared by filemap_fdatawait()
|
/* Put back any errors cleared by filemap_fdatawait()
|
||||||
so they can be caught by someone who can pass them
|
so they can be caught by someone who can pass them
|
||||||
up to user space. */
|
up to user space. */
|
||||||
|
|
||||||
if (error == -ENOSPC)
|
if (error == -ENOSPC)
|
||||||
set_bit(AS_ENOSPC, &mapping->flags);
|
set_bit(AS_ENOSPC, &mapping->flags);
|
||||||
else if (error)
|
else if (error)
|
||||||
set_bit(AS_EIO, &mapping->flags);
|
set_bit(AS_EIO, &mapping->flags);
|
||||||
|
|
||||||
iput(inode);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -138,8 +126,8 @@ void gfs2_page_sync(struct gfs2_glock *gl, int flags)
|
||||||
int gfs2_unstuffer_page(struct gfs2_inode *ip, struct buffer_head *dibh,
|
int gfs2_unstuffer_page(struct gfs2_inode *ip, struct buffer_head *dibh,
|
||||||
uint64_t block, void *private)
|
uint64_t block, void *private)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
||||||
struct inode *inode = ip->i_vnode;
|
struct inode *inode = &ip->i_inode;
|
||||||
struct page *page = (struct page *)private;
|
struct page *page = (struct page *)private;
|
||||||
struct buffer_head *bh;
|
struct buffer_head *bh;
|
||||||
int release = 0;
|
int release = 0;
|
||||||
|
@ -193,8 +181,8 @@ int gfs2_unstuffer_page(struct gfs2_inode *ip, struct buffer_head *dibh,
|
||||||
int gfs2_block_truncate_page(struct address_space *mapping)
|
int gfs2_block_truncate_page(struct address_space *mapping)
|
||||||
{
|
{
|
||||||
struct inode *inode = mapping->host;
|
struct inode *inode = mapping->host;
|
||||||
struct gfs2_inode *ip = inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(inode);
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(inode);
|
||||||
loff_t from = inode->i_size;
|
loff_t from = inode->i_size;
|
||||||
unsigned long index = from >> PAGE_CACHE_SHIFT;
|
unsigned long index = from >> PAGE_CACHE_SHIFT;
|
||||||
unsigned offset = from & (PAGE_CACHE_SIZE-1);
|
unsigned offset = from & (PAGE_CACHE_SIZE-1);
|
||||||
|
|
|
@ -248,7 +248,7 @@ static void slot_put(struct gfs2_quota_data *qd)
|
||||||
static int bh_get(struct gfs2_quota_data *qd)
|
static int bh_get(struct gfs2_quota_data *qd)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = qd->qd_gl->gl_sbd;
|
struct gfs2_sbd *sdp = qd->qd_gl->gl_sbd;
|
||||||
struct gfs2_inode *ip = sdp->sd_qc_inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(sdp->sd_qc_inode);
|
||||||
unsigned int block, offset;
|
unsigned int block, offset;
|
||||||
uint64_t dblock;
|
uint64_t dblock;
|
||||||
int new = 0;
|
int new = 0;
|
||||||
|
@ -266,7 +266,7 @@ static int bh_get(struct gfs2_quota_data *qd)
|
||||||
block = qd->qd_slot / sdp->sd_qc_per_block;
|
block = qd->qd_slot / sdp->sd_qc_per_block;
|
||||||
offset = qd->qd_slot % sdp->sd_qc_per_block;;
|
offset = qd->qd_slot % sdp->sd_qc_per_block;;
|
||||||
|
|
||||||
error = gfs2_block_map(ip->i_vnode, block, &new, &dblock, &boundary);
|
error = gfs2_block_map(&ip->i_inode, block, &new, &dblock, &boundary);
|
||||||
if (error)
|
if (error)
|
||||||
goto fail;
|
goto fail;
|
||||||
error = gfs2_meta_read(ip->i_gl, dblock, DIO_START | DIO_WAIT, &bh);
|
error = gfs2_meta_read(ip->i_gl, dblock, DIO_START | DIO_WAIT, &bh);
|
||||||
|
@ -444,7 +444,7 @@ static void qdsb_put(struct gfs2_quota_data *qd)
|
||||||
|
|
||||||
int gfs2_quota_hold(struct gfs2_inode *ip, uint32_t uid, uint32_t gid)
|
int gfs2_quota_hold(struct gfs2_inode *ip, uint32_t uid, uint32_t gid)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
||||||
struct gfs2_alloc *al = &ip->i_alloc;
|
struct gfs2_alloc *al = &ip->i_alloc;
|
||||||
struct gfs2_quota_data **qd = al->al_qd;
|
struct gfs2_quota_data **qd = al->al_qd;
|
||||||
int error;
|
int error;
|
||||||
|
@ -493,7 +493,7 @@ int gfs2_quota_hold(struct gfs2_inode *ip, uint32_t uid, uint32_t gid)
|
||||||
|
|
||||||
void gfs2_quota_unhold(struct gfs2_inode *ip)
|
void gfs2_quota_unhold(struct gfs2_inode *ip)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
||||||
struct gfs2_alloc *al = &ip->i_alloc;
|
struct gfs2_alloc *al = &ip->i_alloc;
|
||||||
unsigned int x;
|
unsigned int x;
|
||||||
|
|
||||||
|
@ -531,7 +531,7 @@ static int sort_qd(const void *a, const void *b)
|
||||||
static void do_qc(struct gfs2_quota_data *qd, int64_t change)
|
static void do_qc(struct gfs2_quota_data *qd, int64_t change)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = qd->qd_gl->gl_sbd;
|
struct gfs2_sbd *sdp = qd->qd_gl->gl_sbd;
|
||||||
struct gfs2_inode *ip = sdp->sd_qc_inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(sdp->sd_qc_inode);
|
||||||
struct gfs2_quota_change *qc = qd->qd_bh_qc;
|
struct gfs2_quota_change *qc = qd->qd_bh_qc;
|
||||||
int64_t x;
|
int64_t x;
|
||||||
|
|
||||||
|
@ -578,7 +578,7 @@ static void do_qc(struct gfs2_quota_data *qd, int64_t change)
|
||||||
static int gfs2_adjust_quota(struct gfs2_inode *ip, loff_t loc,
|
static int gfs2_adjust_quota(struct gfs2_inode *ip, loff_t loc,
|
||||||
int64_t change, struct gfs2_quota_data *qd)
|
int64_t change, struct gfs2_quota_data *qd)
|
||||||
{
|
{
|
||||||
struct inode *inode = ip->i_vnode;
|
struct inode *inode = &ip->i_inode;
|
||||||
struct address_space *mapping = inode->i_mapping;
|
struct address_space *mapping = inode->i_mapping;
|
||||||
unsigned long index = loc >> PAGE_CACHE_SHIFT;
|
unsigned long index = loc >> PAGE_CACHE_SHIFT;
|
||||||
unsigned offset = loc & (PAGE_CACHE_SHIFT - 1);
|
unsigned offset = loc & (PAGE_CACHE_SHIFT - 1);
|
||||||
|
@ -647,7 +647,7 @@ unlock:
|
||||||
static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda)
|
static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = (*qda)->qd_gl->gl_sbd;
|
struct gfs2_sbd *sdp = (*qda)->qd_gl->gl_sbd;
|
||||||
struct gfs2_inode *ip = sdp->sd_quota_inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(sdp->sd_quota_inode);
|
||||||
unsigned int data_blocks, ind_blocks;
|
unsigned int data_blocks, ind_blocks;
|
||||||
struct file_ra_state ra_state;
|
struct file_ra_state ra_state;
|
||||||
struct gfs2_holder *ghs, i_gh;
|
struct gfs2_holder *ghs, i_gh;
|
||||||
|
@ -716,7 +716,7 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda)
|
||||||
goto out_gunlock;
|
goto out_gunlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
file_ra_state_init(&ra_state, ip->i_vnode->i_mapping);
|
file_ra_state_init(&ra_state, ip->i_inode.i_mapping);
|
||||||
for (x = 0; x < num_qd; x++) {
|
for (x = 0; x < num_qd; x++) {
|
||||||
qd = qda[x];
|
qd = qda[x];
|
||||||
offset = qd2offset(qd);
|
offset = qd2offset(qd);
|
||||||
|
@ -758,7 +758,7 @@ static int do_glock(struct gfs2_quota_data *qd, int force_refresh,
|
||||||
struct gfs2_holder *q_gh)
|
struct gfs2_holder *q_gh)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = qd->qd_gl->gl_sbd;
|
struct gfs2_sbd *sdp = qd->qd_gl->gl_sbd;
|
||||||
struct gfs2_inode *ip = sdp->sd_quota_inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(sdp->sd_quota_inode);
|
||||||
struct gfs2_holder i_gh;
|
struct gfs2_holder i_gh;
|
||||||
struct gfs2_quota q;
|
struct gfs2_quota q;
|
||||||
char buf[sizeof(struct gfs2_quota)];
|
char buf[sizeof(struct gfs2_quota)];
|
||||||
|
@ -829,7 +829,7 @@ static int do_glock(struct gfs2_quota_data *qd, int force_refresh,
|
||||||
|
|
||||||
int gfs2_quota_lock(struct gfs2_inode *ip, uint32_t uid, uint32_t gid)
|
int gfs2_quota_lock(struct gfs2_inode *ip, uint32_t uid, uint32_t gid)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
||||||
struct gfs2_alloc *al = &ip->i_alloc;
|
struct gfs2_alloc *al = &ip->i_alloc;
|
||||||
unsigned int x;
|
unsigned int x;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
@ -958,7 +958,7 @@ static int print_message(struct gfs2_quota_data *qd, char *type)
|
||||||
|
|
||||||
int gfs2_quota_check(struct gfs2_inode *ip, uint32_t uid, uint32_t gid)
|
int gfs2_quota_check(struct gfs2_inode *ip, uint32_t uid, uint32_t gid)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
||||||
struct gfs2_alloc *al = &ip->i_alloc;
|
struct gfs2_alloc *al = &ip->i_alloc;
|
||||||
struct gfs2_quota_data *qd;
|
struct gfs2_quota_data *qd;
|
||||||
int64_t value;
|
int64_t value;
|
||||||
|
@ -1008,7 +1008,7 @@ void gfs2_quota_change(struct gfs2_inode *ip, int64_t change,
|
||||||
unsigned int x;
|
unsigned int x;
|
||||||
unsigned int found = 0;
|
unsigned int found = 0;
|
||||||
|
|
||||||
if (gfs2_assert_warn(ip->i_sbd, change))
|
if (gfs2_assert_warn(GFS2_SB(&ip->i_inode), change))
|
||||||
return;
|
return;
|
||||||
if (ip->i_di.di_flags & GFS2_DIF_SYSTEM)
|
if (ip->i_di.di_flags & GFS2_DIF_SYSTEM)
|
||||||
return;
|
return;
|
||||||
|
@ -1126,7 +1126,7 @@ int gfs2_quota_read(struct gfs2_sbd *sdp, int user, uint32_t id,
|
||||||
|
|
||||||
int gfs2_quota_init(struct gfs2_sbd *sdp)
|
int gfs2_quota_init(struct gfs2_sbd *sdp)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = sdp->sd_qc_inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(sdp->sd_qc_inode);
|
||||||
unsigned int blocks = ip->i_di.di_size >> sdp->sd_sb.sb_bsize_shift;
|
unsigned int blocks = ip->i_di.di_size >> sdp->sd_sb.sb_bsize_shift;
|
||||||
unsigned int x, slot = 0;
|
unsigned int x, slot = 0;
|
||||||
unsigned int found = 0;
|
unsigned int found = 0;
|
||||||
|
@ -1162,7 +1162,7 @@ int gfs2_quota_init(struct gfs2_sbd *sdp)
|
||||||
|
|
||||||
if (!extlen) {
|
if (!extlen) {
|
||||||
int new = 0;
|
int new = 0;
|
||||||
error = gfs2_extent_map(ip->i_vnode, x, &new, &dblock, &extlen);
|
error = gfs2_extent_map(&ip->i_inode, x, &new, &dblock, &extlen);
|
||||||
if (error)
|
if (error)
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,14 +32,14 @@
|
||||||
int gfs2_replay_read_block(struct gfs2_jdesc *jd, unsigned int blk,
|
int gfs2_replay_read_block(struct gfs2_jdesc *jd, unsigned int blk,
|
||||||
struct buffer_head **bh)
|
struct buffer_head **bh)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = jd->jd_inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
|
||||||
struct gfs2_glock *gl = ip->i_gl;
|
struct gfs2_glock *gl = ip->i_gl;
|
||||||
int new = 0;
|
int new = 0;
|
||||||
uint64_t dblock;
|
uint64_t dblock;
|
||||||
uint32_t extlen;
|
uint32_t extlen;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
error = gfs2_extent_map(ip->i_vnode, blk, &new, &dblock, &extlen);
|
error = gfs2_extent_map(&ip->i_inode, blk, &new, &dblock, &extlen);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
if (!dblock) {
|
if (!dblock) {
|
||||||
|
@ -190,7 +190,7 @@ static int find_good_lh(struct gfs2_jdesc *jd, unsigned int *blk,
|
||||||
*blk = 0;
|
*blk = 0;
|
||||||
|
|
||||||
if (*blk == orig_blk) {
|
if (*blk == orig_blk) {
|
||||||
gfs2_consist_inode(jd->jd_inode->u.generic_ip);
|
gfs2_consist_inode(GFS2_I(jd->jd_inode));
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -224,7 +224,7 @@ static int jhead_scan(struct gfs2_jdesc *jd, struct gfs2_log_header *head)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (lh.lh_sequence == head->lh_sequence) {
|
if (lh.lh_sequence == head->lh_sequence) {
|
||||||
gfs2_consist_inode(jd->jd_inode->u.generic_ip);
|
gfs2_consist_inode(GFS2_I(jd->jd_inode));
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
if (lh.lh_sequence < head->lh_sequence)
|
if (lh.lh_sequence < head->lh_sequence)
|
||||||
|
@ -300,8 +300,7 @@ int gfs2_find_jhead(struct gfs2_jdesc *jd, struct gfs2_log_header *head)
|
||||||
static int foreach_descriptor(struct gfs2_jdesc *jd, unsigned int start,
|
static int foreach_descriptor(struct gfs2_jdesc *jd, unsigned int start,
|
||||||
unsigned int end, int pass)
|
unsigned int end, int pass)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = jd->jd_inode->u.generic_ip;
|
struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
|
||||||
struct buffer_head *bh;
|
struct buffer_head *bh;
|
||||||
struct gfs2_log_descriptor *ld;
|
struct gfs2_log_descriptor *ld;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
@ -330,7 +329,7 @@ static int foreach_descriptor(struct gfs2_jdesc *jd, unsigned int start,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (error == 1) {
|
if (error == 1) {
|
||||||
gfs2_consist_inode(jd->jd_inode->u.generic_ip);
|
gfs2_consist_inode(GFS2_I(jd->jd_inode));
|
||||||
error = -EIO;
|
error = -EIO;
|
||||||
}
|
}
|
||||||
brelse(bh);
|
brelse(bh);
|
||||||
|
@ -367,8 +366,8 @@ static int foreach_descriptor(struct gfs2_jdesc *jd, unsigned int start,
|
||||||
|
|
||||||
static int clean_journal(struct gfs2_jdesc *jd, struct gfs2_log_header *head)
|
static int clean_journal(struct gfs2_jdesc *jd, struct gfs2_log_header *head)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = jd->jd_inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
|
||||||
unsigned int lblock;
|
unsigned int lblock;
|
||||||
int new = 0;
|
int new = 0;
|
||||||
uint64_t dblock;
|
uint64_t dblock;
|
||||||
|
@ -380,7 +379,7 @@ static int clean_journal(struct gfs2_jdesc *jd, struct gfs2_log_header *head)
|
||||||
|
|
||||||
lblock = head->lh_blkno;
|
lblock = head->lh_blkno;
|
||||||
gfs2_replay_incr_blk(sdp, &lblock);
|
gfs2_replay_incr_blk(sdp, &lblock);
|
||||||
error = gfs2_block_map(ip->i_vnode, lblock, &new, &dblock, &boundary);
|
error = gfs2_block_map(&ip->i_inode, lblock, &new, &dblock, &boundary);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
if (!dblock) {
|
if (!dblock) {
|
||||||
|
@ -426,8 +425,8 @@ static int clean_journal(struct gfs2_jdesc *jd, struct gfs2_log_header *head)
|
||||||
|
|
||||||
int gfs2_recover_journal(struct gfs2_jdesc *jd)
|
int gfs2_recover_journal(struct gfs2_jdesc *jd)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = jd->jd_inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
|
||||||
struct gfs2_log_header head;
|
struct gfs2_log_header head;
|
||||||
struct gfs2_holder j_gh, ji_gh, t_gh;
|
struct gfs2_holder j_gh, ji_gh, t_gh;
|
||||||
unsigned long t;
|
unsigned long t;
|
||||||
|
|
120
fs/gfs2/rgrp.c
120
fs/gfs2/rgrp.c
|
@ -34,17 +34,19 @@
|
||||||
/*
|
/*
|
||||||
* These routines are used by the resource group routines (rgrp.c)
|
* These routines are used by the resource group routines (rgrp.c)
|
||||||
* to keep track of block allocation. Each block is represented by two
|
* to keep track of block allocation. Each block is represented by two
|
||||||
* bits. One bit indicates whether or not the block is used. (1=used,
|
* bits. So, each byte represents GFS2_NBBY (i.e. 4) blocks.
|
||||||
* 0=free) The other bit indicates whether or not the block contains a
|
*
|
||||||
* dinode or not. (1=dinode, 0=not-dinode) So, each byte represents
|
* 0 = Free
|
||||||
* GFS2_NBBY (i.e. 4) blocks.
|
* 1 = Used (not metadata)
|
||||||
|
* 2 = Unlinked (still in use) inode
|
||||||
|
* 3 = Used (metadata)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static const char valid_change[16] = {
|
static const char valid_change[16] = {
|
||||||
/* current */
|
/* current */
|
||||||
/* n */ 0, 1, 0, 1,
|
/* n */ 0, 1, 1, 1,
|
||||||
/* e */ 1, 0, 0, 0,
|
/* e */ 1, 0, 0, 0,
|
||||||
/* w */ 0, 0, 0, 0,
|
/* w */ 0, 0, 0, 1,
|
||||||
1, 0, 0, 0
|
1, 0, 0, 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -228,26 +230,27 @@ void gfs2_rgrp_verify(struct gfs2_rgrpd *rgd)
|
||||||
tmp = rgd->rd_ri.ri_data -
|
tmp = rgd->rd_ri.ri_data -
|
||||||
rgd->rd_rg.rg_free -
|
rgd->rd_rg.rg_free -
|
||||||
rgd->rd_rg.rg_dinodes;
|
rgd->rd_rg.rg_dinodes;
|
||||||
if (count[1] != tmp) {
|
if (count[1] + count[2] != tmp) {
|
||||||
if (gfs2_consist_rgrpd(rgd))
|
if (gfs2_consist_rgrpd(rgd))
|
||||||
fs_err(sdp, "used data mismatch: %u != %u\n",
|
fs_err(sdp, "used data mismatch: %u != %u\n",
|
||||||
count[1], tmp);
|
count[1], tmp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count[2]) {
|
|
||||||
if (gfs2_consist_rgrpd(rgd))
|
|
||||||
fs_err(sdp, "free metadata mismatch: %u != 0\n",
|
|
||||||
count[2]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count[3] != rgd->rd_rg.rg_dinodes) {
|
if (count[3] != rgd->rd_rg.rg_dinodes) {
|
||||||
if (gfs2_consist_rgrpd(rgd))
|
if (gfs2_consist_rgrpd(rgd))
|
||||||
fs_err(sdp, "used metadata mismatch: %u != %u\n",
|
fs_err(sdp, "used metadata mismatch: %u != %u\n",
|
||||||
count[3], rgd->rd_rg.rg_dinodes);
|
count[3], rgd->rd_rg.rg_dinodes);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (count[2] > count[3]) {
|
||||||
|
if (gfs2_consist_rgrpd(rgd))
|
||||||
|
fs_err(sdp, "unlinked inodes > inodes: %u\n",
|
||||||
|
count[2]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int rgrp_contains_block(struct gfs2_rindex *ri, uint64_t block)
|
static inline int rgrp_contains_block(struct gfs2_rindex *ri, uint64_t block)
|
||||||
|
@ -368,6 +371,9 @@ static int compute_bitstructs(struct gfs2_rgrpd *rgd)
|
||||||
uint32_t bytes_left, bytes;
|
uint32_t bytes_left, bytes;
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
|
if (!length)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
rgd->rd_bits = kcalloc(length, sizeof(struct gfs2_bitmap), GFP_KERNEL);
|
rgd->rd_bits = kcalloc(length, sizeof(struct gfs2_bitmap), GFP_KERNEL);
|
||||||
if (!rgd->rd_bits)
|
if (!rgd->rd_bits)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -433,14 +439,16 @@ static int compute_bitstructs(struct gfs2_rgrpd *rgd)
|
||||||
|
|
||||||
static int gfs2_ri_update(struct gfs2_inode *ip)
|
static int gfs2_ri_update(struct gfs2_inode *ip)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
||||||
struct inode *inode = ip->i_vnode;
|
struct inode *inode = &ip->i_inode;
|
||||||
struct gfs2_rgrpd *rgd;
|
struct gfs2_rgrpd *rgd;
|
||||||
char buf[sizeof(struct gfs2_rindex)];
|
char buf[sizeof(struct gfs2_rindex)];
|
||||||
struct file_ra_state ra_state;
|
struct file_ra_state ra_state;
|
||||||
uint64_t junk = ip->i_di.di_size;
|
uint64_t junk = ip->i_di.di_size;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
printk(KERN_INFO "gfs2_ri_update inode=%p\n", inode);
|
||||||
|
|
||||||
if (do_div(junk, sizeof(struct gfs2_rindex))) {
|
if (do_div(junk, sizeof(struct gfs2_rindex))) {
|
||||||
gfs2_consist_inode(ip);
|
gfs2_consist_inode(ip);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
@ -448,9 +456,12 @@ static int gfs2_ri_update(struct gfs2_inode *ip)
|
||||||
|
|
||||||
clear_rgrpdi(sdp);
|
clear_rgrpdi(sdp);
|
||||||
|
|
||||||
|
printk(KERN_INFO "rgrps cleared\n");
|
||||||
|
|
||||||
file_ra_state_init(&ra_state, inode->i_mapping);
|
file_ra_state_init(&ra_state, inode->i_mapping);
|
||||||
for (sdp->sd_rgrps = 0;; sdp->sd_rgrps++) {
|
for (sdp->sd_rgrps = 0;; sdp->sd_rgrps++) {
|
||||||
loff_t pos = sdp->sd_rgrps * sizeof(struct gfs2_rindex);
|
loff_t pos = sdp->sd_rgrps * sizeof(struct gfs2_rindex);
|
||||||
|
printk(KERN_INFO "reading rgrp %d\n", sdp->sd_rgrps);
|
||||||
error = gfs2_internal_read(ip, &ra_state, buf, &pos,
|
error = gfs2_internal_read(ip, &ra_state, buf, &pos,
|
||||||
sizeof(struct gfs2_rindex));
|
sizeof(struct gfs2_rindex));
|
||||||
if (!error)
|
if (!error)
|
||||||
|
@ -474,13 +485,15 @@ static int gfs2_ri_update(struct gfs2_inode *ip)
|
||||||
list_add_tail(&rgd->rd_list_mru, &sdp->sd_rindex_mru_list);
|
list_add_tail(&rgd->rd_list_mru, &sdp->sd_rindex_mru_list);
|
||||||
|
|
||||||
gfs2_rindex_in(&rgd->rd_ri, buf);
|
gfs2_rindex_in(&rgd->rd_ri, buf);
|
||||||
|
printk(KERN_INFO "compute bitstructs\n");
|
||||||
error = compute_bitstructs(rgd);
|
error = compute_bitstructs(rgd);
|
||||||
if (error)
|
if (error)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
printk(KERN_INFO "gfs2_glock_get\n");
|
||||||
error = gfs2_glock_get(sdp, rgd->rd_ri.ri_addr,
|
error = gfs2_glock_get(sdp, rgd->rd_ri.ri_addr,
|
||||||
&gfs2_rgrp_glops, CREATE, &rgd->rd_gl);
|
&gfs2_rgrp_glops, CREATE, &rgd->rd_gl);
|
||||||
|
printk(KERN_INFO "gfs2_glock_got one\n");
|
||||||
if (error)
|
if (error)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
@ -488,13 +501,14 @@ static int gfs2_ri_update(struct gfs2_inode *ip)
|
||||||
rgd->rd_rg_vn = rgd->rd_gl->gl_vn - 1;
|
rgd->rd_rg_vn = rgd->rd_gl->gl_vn - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printk(KERN_INFO "ok, finished\n");
|
||||||
sdp->sd_rindex_vn = ip->i_gl->gl_vn;
|
sdp->sd_rindex_vn = ip->i_gl->gl_vn;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
printk(KERN_INFO "fail\n");
|
||||||
clear_rgrpdi(sdp);
|
clear_rgrpdi(sdp);
|
||||||
|
printk(KERN_INFO "cleared rgrps\n");
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -518,7 +532,7 @@ static int gfs2_ri_update(struct gfs2_inode *ip)
|
||||||
|
|
||||||
int gfs2_rindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ri_gh)
|
int gfs2_rindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ri_gh)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = sdp->sd_rindex->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(sdp->sd_rindex);
|
||||||
struct gfs2_glock *gl = ip->i_gl;
|
struct gfs2_glock *gl = ip->i_gl;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
@ -583,8 +597,7 @@ int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd)
|
||||||
error = gfs2_meta_reread(sdp, bi->bi_bh, DIO_WAIT);
|
error = gfs2_meta_reread(sdp, bi->bi_bh, DIO_WAIT);
|
||||||
if (error)
|
if (error)
|
||||||
goto fail;
|
goto fail;
|
||||||
if (gfs2_metatype_check(sdp, bi->bi_bh,
|
if (gfs2_metatype_check(sdp, bi->bi_bh, y ? GFS2_METATYPE_RB :
|
||||||
(y) ? GFS2_METATYPE_RB :
|
|
||||||
GFS2_METATYPE_RG)) {
|
GFS2_METATYPE_RG)) {
|
||||||
error = -EIO;
|
error = -EIO;
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -605,7 +618,7 @@ int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
while (x--) {
|
while (x--) {
|
||||||
bi = rgd->rd_bits + x;
|
bi = rgd->rd_bits + x;
|
||||||
brelse(bi->bi_bh);
|
brelse(bi->bi_bh);
|
||||||
|
@ -667,8 +680,7 @@ void gfs2_rgrp_repolish_clones(struct gfs2_rgrpd *rgd)
|
||||||
if (!bi->bi_clone)
|
if (!bi->bi_clone)
|
||||||
continue;
|
continue;
|
||||||
memcpy(bi->bi_clone + bi->bi_offset,
|
memcpy(bi->bi_clone + bi->bi_offset,
|
||||||
bi->bi_bh->b_data + bi->bi_offset,
|
bi->bi_bh->b_data + bi->bi_offset, bi->bi_len);
|
||||||
bi->bi_len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_lock(&sdp->sd_rindex_spin);
|
spin_lock(&sdp->sd_rindex_spin);
|
||||||
|
@ -757,13 +769,11 @@ static struct gfs2_rgrpd *recent_rgrp_first(struct gfs2_sbd *sdp,
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
first:
|
first:
|
||||||
rgd = list_entry(sdp->sd_rindex_recent_list.next, struct gfs2_rgrpd,
|
rgd = list_entry(sdp->sd_rindex_recent_list.next, struct gfs2_rgrpd,
|
||||||
rd_recent);
|
rd_recent);
|
||||||
|
out:
|
||||||
out:
|
|
||||||
spin_unlock(&sdp->sd_rindex_spin);
|
spin_unlock(&sdp->sd_rindex_spin);
|
||||||
|
|
||||||
return rgd;
|
return rgd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -805,9 +815,8 @@ static struct gfs2_rgrpd *recent_rgrp_next(struct gfs2_rgrpd *cur_rgd,
|
||||||
if (!list_empty(head))
|
if (!list_empty(head))
|
||||||
rgd = list_entry(head->next, struct gfs2_rgrpd, rd_recent);
|
rgd = list_entry(head->next, struct gfs2_rgrpd, rd_recent);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
spin_unlock(&sdp->sd_rindex_spin);
|
spin_unlock(&sdp->sd_rindex_spin);
|
||||||
|
|
||||||
return rgd;
|
return rgd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -835,7 +844,7 @@ static void recent_rgrp_add(struct gfs2_rgrpd *new_rgd)
|
||||||
}
|
}
|
||||||
list_add_tail(&new_rgd->rd_recent, &sdp->sd_rindex_recent_list);
|
list_add_tail(&new_rgd->rd_recent, &sdp->sd_rindex_recent_list);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
spin_unlock(&sdp->sd_rindex_spin);
|
spin_unlock(&sdp->sd_rindex_spin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -898,7 +907,7 @@ static void forward_rgrp_set(struct gfs2_sbd *sdp, struct gfs2_rgrpd *rgd)
|
||||||
|
|
||||||
static int get_local_rgrp(struct gfs2_inode *ip)
|
static int get_local_rgrp(struct gfs2_inode *ip)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
||||||
struct gfs2_rgrpd *rgd, *begin = NULL;
|
struct gfs2_rgrpd *rgd, *begin = NULL;
|
||||||
struct gfs2_alloc *al = &ip->i_alloc;
|
struct gfs2_alloc *al = &ip->i_alloc;
|
||||||
int flags = LM_FLAG_TRY;
|
int flags = LM_FLAG_TRY;
|
||||||
|
@ -965,7 +974,7 @@ static int get_local_rgrp(struct gfs2_inode *ip)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
ip->i_last_rg_alloc = rgd->rd_ri.ri_addr;
|
ip->i_last_rg_alloc = rgd->rd_ri.ri_addr;
|
||||||
|
|
||||||
if (begin) {
|
if (begin) {
|
||||||
|
@ -988,7 +997,7 @@ static int get_local_rgrp(struct gfs2_inode *ip)
|
||||||
|
|
||||||
int gfs2_inplace_reserve_i(struct gfs2_inode *ip, char *file, unsigned int line)
|
int gfs2_inplace_reserve_i(struct gfs2_inode *ip, char *file, unsigned int line)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
||||||
struct gfs2_alloc *al = &ip->i_alloc;
|
struct gfs2_alloc *al = &ip->i_alloc;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
@ -1020,7 +1029,7 @@ int gfs2_inplace_reserve_i(struct gfs2_inode *ip, char *file, unsigned int line)
|
||||||
|
|
||||||
void gfs2_inplace_release(struct gfs2_inode *ip)
|
void gfs2_inplace_release(struct gfs2_inode *ip)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
||||||
struct gfs2_alloc *al = &ip->i_alloc;
|
struct gfs2_alloc *al = &ip->i_alloc;
|
||||||
|
|
||||||
if (gfs2_assert_warn(sdp, al->al_alloced <= al->al_requested) == -1)
|
if (gfs2_assert_warn(sdp, al->al_alloced <= al->al_requested) == -1)
|
||||||
|
@ -1061,8 +1070,7 @@ unsigned char gfs2_get_block_type(struct gfs2_rgrpd *rgd, uint64_t block)
|
||||||
gfs2_assert(rgd->rd_sbd, buf < length);
|
gfs2_assert(rgd->rd_sbd, buf < length);
|
||||||
buf_block = rgrp_block - bi->bi_start * GFS2_NBBY;
|
buf_block = rgrp_block - bi->bi_start * GFS2_NBBY;
|
||||||
|
|
||||||
type = gfs2_testbit(rgd,
|
type = gfs2_testbit(rgd, bi->bi_bh->b_data + bi->bi_offset,
|
||||||
bi->bi_bh->b_data + bi->bi_offset,
|
|
||||||
bi->bi_len, buf_block);
|
bi->bi_len, buf_block);
|
||||||
|
|
||||||
return type;
|
return type;
|
||||||
|
@ -1210,7 +1218,7 @@ static struct gfs2_rgrpd *rgblk_free(struct gfs2_sbd *sdp, uint64_t bstart,
|
||||||
|
|
||||||
uint64_t gfs2_alloc_data(struct gfs2_inode *ip)
|
uint64_t gfs2_alloc_data(struct gfs2_inode *ip)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
||||||
struct gfs2_alloc *al = &ip->i_alloc;
|
struct gfs2_alloc *al = &ip->i_alloc;
|
||||||
struct gfs2_rgrpd *rgd = al->al_rgd;
|
struct gfs2_rgrpd *rgd = al->al_rgd;
|
||||||
uint32_t goal, blk;
|
uint32_t goal, blk;
|
||||||
|
@ -1254,7 +1262,7 @@ uint64_t gfs2_alloc_data(struct gfs2_inode *ip)
|
||||||
|
|
||||||
uint64_t gfs2_alloc_meta(struct gfs2_inode *ip)
|
uint64_t gfs2_alloc_meta(struct gfs2_inode *ip)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
||||||
struct gfs2_alloc *al = &ip->i_alloc;
|
struct gfs2_alloc *al = &ip->i_alloc;
|
||||||
struct gfs2_rgrpd *rgd = al->al_rgd;
|
struct gfs2_rgrpd *rgd = al->al_rgd;
|
||||||
uint32_t goal, blk;
|
uint32_t goal, blk;
|
||||||
|
@ -1299,7 +1307,7 @@ uint64_t gfs2_alloc_meta(struct gfs2_inode *ip)
|
||||||
|
|
||||||
uint64_t gfs2_alloc_di(struct gfs2_inode *dip)
|
uint64_t gfs2_alloc_di(struct gfs2_inode *dip)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = dip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
|
||||||
struct gfs2_alloc *al = &dip->i_alloc;
|
struct gfs2_alloc *al = &dip->i_alloc;
|
||||||
struct gfs2_rgrpd *rgd = al->al_rgd;
|
struct gfs2_rgrpd *rgd = al->al_rgd;
|
||||||
uint32_t blk;
|
uint32_t blk;
|
||||||
|
@ -1341,7 +1349,7 @@ uint64_t gfs2_alloc_di(struct gfs2_inode *dip)
|
||||||
|
|
||||||
void gfs2_free_data(struct gfs2_inode *ip, uint64_t bstart, uint32_t blen)
|
void gfs2_free_data(struct gfs2_inode *ip, uint64_t bstart, uint32_t blen)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
||||||
struct gfs2_rgrpd *rgd;
|
struct gfs2_rgrpd *rgd;
|
||||||
|
|
||||||
rgd = rgblk_free(sdp, bstart, blen, GFS2_BLKST_FREE);
|
rgd = rgblk_free(sdp, bstart, blen, GFS2_BLKST_FREE);
|
||||||
|
@ -1370,7 +1378,7 @@ void gfs2_free_data(struct gfs2_inode *ip, uint64_t bstart, uint32_t blen)
|
||||||
|
|
||||||
void gfs2_free_meta(struct gfs2_inode *ip, uint64_t bstart, uint32_t blen)
|
void gfs2_free_meta(struct gfs2_inode *ip, uint64_t bstart, uint32_t blen)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
||||||
struct gfs2_rgrpd *rgd;
|
struct gfs2_rgrpd *rgd;
|
||||||
|
|
||||||
rgd = rgblk_free(sdp, bstart, blen, GFS2_BLKST_FREE);
|
rgd = rgblk_free(sdp, bstart, blen, GFS2_BLKST_FREE);
|
||||||
|
@ -1385,11 +1393,25 @@ void gfs2_free_meta(struct gfs2_inode *ip, uint64_t bstart, uint32_t blen)
|
||||||
gfs2_trans_add_rg(rgd);
|
gfs2_trans_add_rg(rgd);
|
||||||
|
|
||||||
gfs2_statfs_change(sdp, 0, +blen, 0);
|
gfs2_statfs_change(sdp, 0, +blen, 0);
|
||||||
gfs2_quota_change(ip, -(int64_t)blen,
|
gfs2_quota_change(ip, -(int64_t)blen, ip->i_di.di_uid, ip->i_di.di_gid);
|
||||||
ip->i_di.di_uid, ip->i_di.di_gid);
|
|
||||||
gfs2_meta_wipe(ip, bstart, blen);
|
gfs2_meta_wipe(ip, bstart, blen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gfs2_unlink_di(struct inode *inode)
|
||||||
|
{
|
||||||
|
struct gfs2_inode *ip = GFS2_I(inode);
|
||||||
|
struct gfs2_sbd *sdp = GFS2_SB(inode);
|
||||||
|
struct gfs2_rgrpd *rgd;
|
||||||
|
u64 blkno = ip->i_num.no_addr;
|
||||||
|
|
||||||
|
rgd = rgblk_free(sdp, blkno, 1, GFS2_BLKST_UNLINKED);
|
||||||
|
if (!rgd)
|
||||||
|
return;
|
||||||
|
gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1);
|
||||||
|
gfs2_rgrp_out(&rgd->rd_rg, rgd->rd_bits[0].bi_bh->b_data);
|
||||||
|
gfs2_trans_add_rg(rgd);
|
||||||
|
}
|
||||||
|
|
||||||
void gfs2_free_uninit_di(struct gfs2_rgrpd *rgd, uint64_t blkno)
|
void gfs2_free_uninit_di(struct gfs2_rgrpd *rgd, uint64_t blkno)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = rgd->rd_sbd;
|
struct gfs2_sbd *sdp = rgd->rd_sbd;
|
||||||
|
@ -1412,12 +1434,6 @@ void gfs2_free_uninit_di(struct gfs2_rgrpd *rgd, uint64_t blkno)
|
||||||
gfs2_trans_add_rg(rgd);
|
gfs2_trans_add_rg(rgd);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* gfs2_free_uninit_di - free a dinode block
|
|
||||||
* @rgd: the resource group that contains the dinode
|
|
||||||
* @ip: the inode
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip)
|
void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip)
|
||||||
{
|
{
|
||||||
|
|
|
@ -45,6 +45,7 @@ void gfs2_free_data(struct gfs2_inode *ip, uint64_t bstart, uint32_t blen);
|
||||||
void gfs2_free_meta(struct gfs2_inode *ip, uint64_t bstart, uint32_t blen);
|
void gfs2_free_meta(struct gfs2_inode *ip, uint64_t bstart, uint32_t blen);
|
||||||
void gfs2_free_uninit_di(struct gfs2_rgrpd *rgd, uint64_t blkno);
|
void gfs2_free_uninit_di(struct gfs2_rgrpd *rgd, uint64_t blkno);
|
||||||
void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip);
|
void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip);
|
||||||
|
void gfs2_unlink_di(struct inode *inode);
|
||||||
|
|
||||||
struct gfs2_rgrp_list {
|
struct gfs2_rgrp_list {
|
||||||
unsigned int rl_rgrps;
|
unsigned int rl_rgrps;
|
||||||
|
|
|
@ -31,7 +31,6 @@
|
||||||
#include "rgrp.h"
|
#include "rgrp.h"
|
||||||
#include "super.h"
|
#include "super.h"
|
||||||
#include "trans.h"
|
#include "trans.h"
|
||||||
#include "unlinked.h"
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -55,7 +54,6 @@ void gfs2_tune_init(struct gfs2_tune *gt)
|
||||||
gt->gt_recoverd_secs = 60;
|
gt->gt_recoverd_secs = 60;
|
||||||
gt->gt_logd_secs = 1;
|
gt->gt_logd_secs = 1;
|
||||||
gt->gt_quotad_secs = 5;
|
gt->gt_quotad_secs = 5;
|
||||||
gt->gt_inoded_secs = 15;
|
|
||||||
gt->gt_quota_simul_sync = 64;
|
gt->gt_quota_simul_sync = 64;
|
||||||
gt->gt_quota_warn_period = 10;
|
gt->gt_quota_warn_period = 10;
|
||||||
gt->gt_quota_scale_num = 1;
|
gt->gt_quota_scale_num = 1;
|
||||||
|
@ -202,9 +200,6 @@ int gfs2_read_sb(struct gfs2_sbd *sdp, struct gfs2_glock *gl, int silent)
|
||||||
sdp->sd_hash_bsize = sdp->sd_sb.sb_bsize / 2;
|
sdp->sd_hash_bsize = sdp->sd_sb.sb_bsize / 2;
|
||||||
sdp->sd_hash_bsize_shift = sdp->sd_sb.sb_bsize_shift - 1;
|
sdp->sd_hash_bsize_shift = sdp->sd_sb.sb_bsize_shift - 1;
|
||||||
sdp->sd_hash_ptrs = sdp->sd_hash_bsize / sizeof(uint64_t);
|
sdp->sd_hash_ptrs = sdp->sd_hash_bsize / sizeof(uint64_t);
|
||||||
sdp->sd_ut_per_block = (sdp->sd_sb.sb_bsize -
|
|
||||||
sizeof(struct gfs2_meta_header)) /
|
|
||||||
sizeof(struct gfs2_unlinked_tag);
|
|
||||||
sdp->sd_qc_per_block = (sdp->sd_sb.sb_bsize -
|
sdp->sd_qc_per_block = (sdp->sd_sb.sb_bsize -
|
||||||
sizeof(struct gfs2_meta_header)) /
|
sizeof(struct gfs2_meta_header)) /
|
||||||
sizeof(struct gfs2_quota_change);
|
sizeof(struct gfs2_quota_change);
|
||||||
|
@ -277,7 +272,7 @@ int gfs2_read_sb(struct gfs2_sbd *sdp, struct gfs2_glock *gl, int silent)
|
||||||
|
|
||||||
int gfs2_jindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ji_gh)
|
int gfs2_jindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ji_gh)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *dip = sdp->sd_jindex->u.generic_ip;
|
struct gfs2_inode *dip = GFS2_I(sdp->sd_jindex);
|
||||||
struct qstr name;
|
struct qstr name;
|
||||||
char buf[20];
|
char buf[20];
|
||||||
struct gfs2_jdesc *jd;
|
struct gfs2_jdesc *jd;
|
||||||
|
@ -296,8 +291,7 @@ int gfs2_jindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ji_gh)
|
||||||
name.len = sprintf(buf, "journal%u", sdp->sd_journals);
|
name.len = sprintf(buf, "journal%u", sdp->sd_journals);
|
||||||
name.hash = gfs2_disk_hash(name.name, name.len);
|
name.hash = gfs2_disk_hash(name.name, name.len);
|
||||||
|
|
||||||
error = gfs2_dir_search(sdp->sd_jindex,
|
error = gfs2_dir_search(sdp->sd_jindex, &name, NULL, NULL);
|
||||||
&name, NULL, NULL);
|
|
||||||
if (error == -ENOENT) {
|
if (error == -ENOENT) {
|
||||||
error = 0;
|
error = 0;
|
||||||
break;
|
break;
|
||||||
|
@ -423,22 +417,19 @@ struct gfs2_jdesc *gfs2_jdesc_find_dirty(struct gfs2_sbd *sdp)
|
||||||
|
|
||||||
int gfs2_jdesc_check(struct gfs2_jdesc *jd)
|
int gfs2_jdesc_check(struct gfs2_jdesc *jd)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = jd->jd_inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
|
||||||
int ar;
|
int ar;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
if (ip->i_di.di_size < (8 << 20) ||
|
if (ip->i_di.di_size < (8 << 20) || ip->i_di.di_size > (1 << 30) ||
|
||||||
ip->i_di.di_size > (1 << 30) ||
|
|
||||||
(ip->i_di.di_size & (sdp->sd_sb.sb_bsize - 1))) {
|
(ip->i_di.di_size & (sdp->sd_sb.sb_bsize - 1))) {
|
||||||
gfs2_consist_inode(ip);
|
gfs2_consist_inode(ip);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
jd->jd_blocks = ip->i_di.di_size >> sdp->sd_sb.sb_bsize_shift;
|
jd->jd_blocks = ip->i_di.di_size >> sdp->sd_sb.sb_bsize_shift;
|
||||||
|
|
||||||
error = gfs2_write_alloc_required(ip,
|
error = gfs2_write_alloc_required(ip, 0, ip->i_di.di_size, &ar);
|
||||||
0, ip->i_di.di_size,
|
|
||||||
&ar);
|
|
||||||
if (!error && ar) {
|
if (!error && ar) {
|
||||||
gfs2_consist_inode(ip);
|
gfs2_consist_inode(ip);
|
||||||
error = -EIO;
|
error = -EIO;
|
||||||
|
@ -456,7 +447,7 @@ int gfs2_jdesc_check(struct gfs2_jdesc *jd)
|
||||||
|
|
||||||
int gfs2_make_fs_rw(struct gfs2_sbd *sdp)
|
int gfs2_make_fs_rw(struct gfs2_sbd *sdp)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = sdp->sd_jdesc->jd_inode->u.generic_ip;
|
struct gfs2_inode *ip = GFS2_I(sdp->sd_jdesc->jd_inode);
|
||||||
struct gfs2_glock *j_gl = ip->i_gl;
|
struct gfs2_glock *j_gl = ip->i_gl;
|
||||||
struct gfs2_holder t_gh;
|
struct gfs2_holder t_gh;
|
||||||
struct gfs2_log_header head;
|
struct gfs2_log_header head;
|
||||||
|
@ -484,9 +475,6 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp)
|
||||||
sdp->sd_log_sequence = head.lh_sequence + 1;
|
sdp->sd_log_sequence = head.lh_sequence + 1;
|
||||||
gfs2_log_pointers_init(sdp, head.lh_blkno);
|
gfs2_log_pointers_init(sdp, head.lh_blkno);
|
||||||
|
|
||||||
error = gfs2_unlinked_init(sdp);
|
|
||||||
if (error)
|
|
||||||
goto fail;
|
|
||||||
error = gfs2_quota_init(sdp);
|
error = gfs2_quota_init(sdp);
|
||||||
if (error)
|
if (error)
|
||||||
goto fail_unlinked;
|
goto fail_unlinked;
|
||||||
|
@ -498,7 +486,6 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail_unlinked:
|
fail_unlinked:
|
||||||
gfs2_unlinked_cleanup(sdp);
|
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
t_gh.gh_flags |= GL_NOCACHE;
|
t_gh.gh_flags |= GL_NOCACHE;
|
||||||
|
@ -519,7 +506,6 @@ int gfs2_make_fs_ro(struct gfs2_sbd *sdp)
|
||||||
struct gfs2_holder t_gh;
|
struct gfs2_holder t_gh;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
gfs2_unlinked_dealloc(sdp);
|
|
||||||
gfs2_quota_sync(sdp);
|
gfs2_quota_sync(sdp);
|
||||||
gfs2_statfs_sync(sdp);
|
gfs2_statfs_sync(sdp);
|
||||||
|
|
||||||
|
@ -537,7 +523,6 @@ int gfs2_make_fs_ro(struct gfs2_sbd *sdp)
|
||||||
if (t_gh.gh_gl)
|
if (t_gh.gh_gl)
|
||||||
gfs2_glock_dq_uninit(&t_gh);
|
gfs2_glock_dq_uninit(&t_gh);
|
||||||
|
|
||||||
gfs2_unlinked_cleanup(sdp);
|
|
||||||
gfs2_quota_cleanup(sdp);
|
gfs2_quota_cleanup(sdp);
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
|
@ -545,9 +530,9 @@ int gfs2_make_fs_ro(struct gfs2_sbd *sdp)
|
||||||
|
|
||||||
int gfs2_statfs_init(struct gfs2_sbd *sdp)
|
int gfs2_statfs_init(struct gfs2_sbd *sdp)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *m_ip = sdp->sd_statfs_inode->u.generic_ip;
|
struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
|
||||||
struct gfs2_statfs_change *m_sc = &sdp->sd_statfs_master;
|
struct gfs2_statfs_change *m_sc = &sdp->sd_statfs_master;
|
||||||
struct gfs2_inode *l_ip = sdp->sd_sc_inode->u.generic_ip;
|
struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode);
|
||||||
struct gfs2_statfs_change *l_sc = &sdp->sd_statfs_local;
|
struct gfs2_statfs_change *l_sc = &sdp->sd_statfs_local;
|
||||||
struct buffer_head *m_bh, *l_bh;
|
struct buffer_head *m_bh, *l_bh;
|
||||||
struct gfs2_holder gh;
|
struct gfs2_holder gh;
|
||||||
|
@ -594,7 +579,7 @@ int gfs2_statfs_init(struct gfs2_sbd *sdp)
|
||||||
void gfs2_statfs_change(struct gfs2_sbd *sdp, int64_t total, int64_t free,
|
void gfs2_statfs_change(struct gfs2_sbd *sdp, int64_t total, int64_t free,
|
||||||
int64_t dinodes)
|
int64_t dinodes)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *l_ip = sdp->sd_sc_inode->u.generic_ip;
|
struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode);
|
||||||
struct gfs2_statfs_change *l_sc = &sdp->sd_statfs_local;
|
struct gfs2_statfs_change *l_sc = &sdp->sd_statfs_local;
|
||||||
struct buffer_head *l_bh;
|
struct buffer_head *l_bh;
|
||||||
int error;
|
int error;
|
||||||
|
@ -620,8 +605,8 @@ void gfs2_statfs_change(struct gfs2_sbd *sdp, int64_t total, int64_t free,
|
||||||
|
|
||||||
int gfs2_statfs_sync(struct gfs2_sbd *sdp)
|
int gfs2_statfs_sync(struct gfs2_sbd *sdp)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *m_ip = sdp->sd_statfs_inode->u.generic_ip;
|
struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
|
||||||
struct gfs2_inode *l_ip = sdp->sd_sc_inode->u.generic_ip;
|
struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode);
|
||||||
struct gfs2_statfs_change *m_sc = &sdp->sd_statfs_master;
|
struct gfs2_statfs_change *m_sc = &sdp->sd_statfs_master;
|
||||||
struct gfs2_statfs_change *l_sc = &sdp->sd_statfs_local;
|
struct gfs2_statfs_change *l_sc = &sdp->sd_statfs_local;
|
||||||
struct gfs2_holder gh;
|
struct gfs2_holder gh;
|
||||||
|
@ -852,10 +837,8 @@ static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp,
|
||||||
error = -ENOMEM;
|
error = -ENOMEM;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
ip = jd->jd_inode->u.generic_ip;
|
ip = GFS2_I(jd->jd_inode);
|
||||||
error = gfs2_glock_nq_init(ip->i_gl,
|
error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, 0, &lfcc->gh);
|
||||||
LM_ST_SHARED, 0,
|
|
||||||
&lfcc->gh);
|
|
||||||
if (error) {
|
if (error) {
|
||||||
kfree(lfcc);
|
kfree(lfcc);
|
||||||
goto out;
|
goto out;
|
||||||
|
|
|
@ -453,7 +453,6 @@ TUNE_ATTR_DAEMON(scand_secs, scand_process);
|
||||||
TUNE_ATTR_DAEMON(recoverd_secs, recoverd_process);
|
TUNE_ATTR_DAEMON(recoverd_secs, recoverd_process);
|
||||||
TUNE_ATTR_DAEMON(logd_secs, logd_process);
|
TUNE_ATTR_DAEMON(logd_secs, logd_process);
|
||||||
TUNE_ATTR_DAEMON(quotad_secs, quotad_process);
|
TUNE_ATTR_DAEMON(quotad_secs, quotad_process);
|
||||||
TUNE_ATTR_DAEMON(inoded_secs, inoded_process);
|
|
||||||
TUNE_ATTR_3(quota_scale, quota_scale_show, quota_scale_store);
|
TUNE_ATTR_3(quota_scale, quota_scale_show, quota_scale_store);
|
||||||
|
|
||||||
static struct attribute *tune_attrs[] = {
|
static struct attribute *tune_attrs[] = {
|
||||||
|
@ -485,7 +484,6 @@ static struct attribute *tune_attrs[] = {
|
||||||
&tune_attr_recoverd_secs.attr,
|
&tune_attr_recoverd_secs.attr,
|
||||||
&tune_attr_logd_secs.attr,
|
&tune_attr_logd_secs.attr,
|
||||||
&tune_attr_quotad_secs.attr,
|
&tune_attr_quotad_secs.attr,
|
||||||
&tune_attr_inoded_secs.attr,
|
|
||||||
&tune_attr_quota_scale.attr,
|
&tune_attr_quota_scale.attr,
|
||||||
&tune_attr_new_files_jdata.attr,
|
&tune_attr_new_files_jdata.attr,
|
||||||
&tune_attr_new_files_directio.attr,
|
&tune_attr_new_files_directio.attr,
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
#define RES_LEAF 1
|
#define RES_LEAF 1
|
||||||
#define RES_RG_BIT 2
|
#define RES_RG_BIT 2
|
||||||
#define RES_EATTR 1
|
#define RES_EATTR 1
|
||||||
#define RES_UNLINKED 1
|
|
||||||
#define RES_STATFS 1
|
#define RES_STATFS 1
|
||||||
#define RES_QUOTA 2
|
#define RES_QUOTA 2
|
||||||
|
|
||||||
|
|
|
@ -1,459 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
|
|
||||||
* Copyright (C) 2004-2006 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
|
|
||||||
* of the GNU General Public License v.2.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/sched.h>
|
|
||||||
#include <linux/slab.h>
|
|
||||||
#include <linux/spinlock.h>
|
|
||||||
#include <linux/completion.h>
|
|
||||||
#include <linux/buffer_head.h>
|
|
||||||
#include <linux/kthread.h>
|
|
||||||
#include <linux/gfs2_ondisk.h>
|
|
||||||
|
|
||||||
#include "gfs2.h"
|
|
||||||
#include "lm_interface.h"
|
|
||||||
#include "incore.h"
|
|
||||||
#include "bmap.h"
|
|
||||||
#include "inode.h"
|
|
||||||
#include "meta_io.h"
|
|
||||||
#include "trans.h"
|
|
||||||
#include "unlinked.h"
|
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
static int munge_ondisk(struct gfs2_sbd *sdp, unsigned int slot,
|
|
||||||
struct gfs2_unlinked_tag *ut)
|
|
||||||
{
|
|
||||||
struct gfs2_inode *ip = sdp->sd_ut_inode->u.generic_ip;
|
|
||||||
unsigned int block, offset;
|
|
||||||
uint64_t dblock;
|
|
||||||
int new = 0;
|
|
||||||
struct buffer_head *bh;
|
|
||||||
int error;
|
|
||||||
int boundary;
|
|
||||||
|
|
||||||
block = slot / sdp->sd_ut_per_block;
|
|
||||||
offset = slot % sdp->sd_ut_per_block;
|
|
||||||
|
|
||||||
error = gfs2_block_map(ip->i_vnode, block, &new, &dblock, &boundary);
|
|
||||||
if (error)
|
|
||||||
return error;
|
|
||||||
error = gfs2_meta_read(ip->i_gl, dblock, DIO_START | DIO_WAIT, &bh);
|
|
||||||
if (error)
|
|
||||||
return error;
|
|
||||||
if (gfs2_metatype_check(sdp, bh, GFS2_METATYPE_UT)) {
|
|
||||||
error = -EIO;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex_lock(&sdp->sd_unlinked_mutex);
|
|
||||||
gfs2_trans_add_bh(ip->i_gl, bh, 1);
|
|
||||||
gfs2_unlinked_tag_out(ut, bh->b_data +
|
|
||||||
sizeof(struct gfs2_meta_header) +
|
|
||||||
offset * sizeof(struct gfs2_unlinked_tag));
|
|
||||||
mutex_unlock(&sdp->sd_unlinked_mutex);
|
|
||||||
|
|
||||||
out:
|
|
||||||
brelse(bh);
|
|
||||||
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ul_hash(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul)
|
|
||||||
{
|
|
||||||
spin_lock(&sdp->sd_unlinked_spin);
|
|
||||||
list_add(&ul->ul_list, &sdp->sd_unlinked_list);
|
|
||||||
gfs2_assert(sdp, ul->ul_count);
|
|
||||||
ul->ul_count++;
|
|
||||||
atomic_inc(&sdp->sd_unlinked_count);
|
|
||||||
spin_unlock(&sdp->sd_unlinked_spin);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ul_unhash(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul)
|
|
||||||
{
|
|
||||||
spin_lock(&sdp->sd_unlinked_spin);
|
|
||||||
list_del_init(&ul->ul_list);
|
|
||||||
gfs2_assert(sdp, ul->ul_count > 1);
|
|
||||||
ul->ul_count--;
|
|
||||||
gfs2_assert_warn(sdp, atomic_read(&sdp->sd_unlinked_count) > 0);
|
|
||||||
atomic_dec(&sdp->sd_unlinked_count);
|
|
||||||
spin_unlock(&sdp->sd_unlinked_spin);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct gfs2_unlinked *ul_fish(struct gfs2_sbd *sdp)
|
|
||||||
{
|
|
||||||
struct list_head *head;
|
|
||||||
struct gfs2_unlinked *ul;
|
|
||||||
int found = 0;
|
|
||||||
|
|
||||||
if (sdp->sd_vfs->s_flags & MS_RDONLY)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
spin_lock(&sdp->sd_unlinked_spin);
|
|
||||||
|
|
||||||
head = &sdp->sd_unlinked_list;
|
|
||||||
|
|
||||||
list_for_each_entry(ul, head, ul_list) {
|
|
||||||
if (test_bit(ULF_LOCKED, &ul->ul_flags))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
list_move_tail(&ul->ul_list, head);
|
|
||||||
ul->ul_count++;
|
|
||||||
set_bit(ULF_LOCKED, &ul->ul_flags);
|
|
||||||
found = 1;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found)
|
|
||||||
ul = NULL;
|
|
||||||
|
|
||||||
spin_unlock(&sdp->sd_unlinked_spin);
|
|
||||||
|
|
||||||
return ul;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* enforce_limit - limit the number of inodes waiting to be deallocated
|
|
||||||
* @sdp: the filesystem
|
|
||||||
*
|
|
||||||
* Returns: errno
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void enforce_limit(struct gfs2_sbd *sdp)
|
|
||||||
{
|
|
||||||
unsigned int tries = 0, min = 0;
|
|
||||||
int error;
|
|
||||||
|
|
||||||
if (atomic_read(&sdp->sd_unlinked_count) <
|
|
||||||
gfs2_tune_get(sdp, gt_ilimit))
|
|
||||||
return;
|
|
||||||
|
|
||||||
tries = gfs2_tune_get(sdp, gt_ilimit_tries);
|
|
||||||
min = gfs2_tune_get(sdp, gt_ilimit_min);
|
|
||||||
|
|
||||||
while (tries--) {
|
|
||||||
struct gfs2_unlinked *ul = ul_fish(sdp);
|
|
||||||
if (!ul)
|
|
||||||
break;
|
|
||||||
error = gfs2_inode_dealloc(sdp, ul);
|
|
||||||
gfs2_unlinked_put(sdp, ul);
|
|
||||||
|
|
||||||
if (!error) {
|
|
||||||
if (!--min)
|
|
||||||
break;
|
|
||||||
} else if (error != 1)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct gfs2_unlinked *ul_alloc(struct gfs2_sbd *sdp)
|
|
||||||
{
|
|
||||||
struct gfs2_unlinked *ul;
|
|
||||||
|
|
||||||
ul = kzalloc(sizeof(struct gfs2_unlinked), GFP_KERNEL);
|
|
||||||
if (ul) {
|
|
||||||
INIT_LIST_HEAD(&ul->ul_list);
|
|
||||||
ul->ul_count = 1;
|
|
||||||
set_bit(ULF_LOCKED, &ul->ul_flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ul;
|
|
||||||
}
|
|
||||||
|
|
||||||
int gfs2_unlinked_get(struct gfs2_sbd *sdp, struct gfs2_unlinked **ul)
|
|
||||||
{
|
|
||||||
unsigned int c, o = 0, b;
|
|
||||||
unsigned char byte = 0;
|
|
||||||
|
|
||||||
enforce_limit(sdp);
|
|
||||||
|
|
||||||
*ul = ul_alloc(sdp);
|
|
||||||
if (!*ul)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
spin_lock(&sdp->sd_unlinked_spin);
|
|
||||||
|
|
||||||
for (c = 0; c < sdp->sd_unlinked_chunks; c++)
|
|
||||||
for (o = 0; o < PAGE_SIZE; o++) {
|
|
||||||
byte = sdp->sd_unlinked_bitmap[c][o];
|
|
||||||
if (byte != 0xFF)
|
|
||||||
goto found;
|
|
||||||
}
|
|
||||||
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
found:
|
|
||||||
for (b = 0; b < 8; b++)
|
|
||||||
if (!(byte & (1 << b)))
|
|
||||||
break;
|
|
||||||
(*ul)->ul_slot = c * (8 * PAGE_SIZE) + o * 8 + b;
|
|
||||||
|
|
||||||
if ((*ul)->ul_slot >= sdp->sd_unlinked_slots)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
sdp->sd_unlinked_bitmap[c][o] |= 1 << b;
|
|
||||||
|
|
||||||
spin_unlock(&sdp->sd_unlinked_spin);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
fail:
|
|
||||||
spin_unlock(&sdp->sd_unlinked_spin);
|
|
||||||
kfree(*ul);
|
|
||||||
return -ENOSPC;
|
|
||||||
}
|
|
||||||
|
|
||||||
void gfs2_unlinked_put(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul)
|
|
||||||
{
|
|
||||||
gfs2_assert_warn(sdp, test_and_clear_bit(ULF_LOCKED, &ul->ul_flags));
|
|
||||||
|
|
||||||
spin_lock(&sdp->sd_unlinked_spin);
|
|
||||||
gfs2_assert(sdp, ul->ul_count);
|
|
||||||
ul->ul_count--;
|
|
||||||
if (!ul->ul_count) {
|
|
||||||
gfs2_icbit_munge(sdp, sdp->sd_unlinked_bitmap, ul->ul_slot, 0);
|
|
||||||
spin_unlock(&sdp->sd_unlinked_spin);
|
|
||||||
kfree(ul);
|
|
||||||
} else
|
|
||||||
spin_unlock(&sdp->sd_unlinked_spin);
|
|
||||||
}
|
|
||||||
|
|
||||||
int gfs2_unlinked_ondisk_add(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul)
|
|
||||||
{
|
|
||||||
int error;
|
|
||||||
|
|
||||||
gfs2_assert_warn(sdp, test_bit(ULF_LOCKED, &ul->ul_flags));
|
|
||||||
gfs2_assert_warn(sdp, list_empty(&ul->ul_list));
|
|
||||||
|
|
||||||
error = munge_ondisk(sdp, ul->ul_slot, &ul->ul_ut);
|
|
||||||
if (!error)
|
|
||||||
ul_hash(sdp, ul);
|
|
||||||
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
int gfs2_unlinked_ondisk_munge(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul)
|
|
||||||
{
|
|
||||||
int error;
|
|
||||||
|
|
||||||
gfs2_assert_warn(sdp, test_bit(ULF_LOCKED, &ul->ul_flags));
|
|
||||||
gfs2_assert_warn(sdp, !list_empty(&ul->ul_list));
|
|
||||||
|
|
||||||
error = munge_ondisk(sdp, ul->ul_slot, &ul->ul_ut);
|
|
||||||
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
int gfs2_unlinked_ondisk_rm(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul)
|
|
||||||
{
|
|
||||||
struct gfs2_unlinked_tag ut;
|
|
||||||
int error;
|
|
||||||
|
|
||||||
gfs2_assert_warn(sdp, test_bit(ULF_LOCKED, &ul->ul_flags));
|
|
||||||
gfs2_assert_warn(sdp, !list_empty(&ul->ul_list));
|
|
||||||
|
|
||||||
memset(&ut, 0, sizeof(struct gfs2_unlinked_tag));
|
|
||||||
|
|
||||||
error = munge_ondisk(sdp, ul->ul_slot, &ut);
|
|
||||||
if (error)
|
|
||||||
return error;
|
|
||||||
|
|
||||||
ul_unhash(sdp, ul);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* gfs2_unlinked_dealloc - Go through the list of inodes to be deallocated
|
|
||||||
* @sdp: the filesystem
|
|
||||||
*
|
|
||||||
* Returns: errno
|
|
||||||
*/
|
|
||||||
|
|
||||||
int gfs2_unlinked_dealloc(struct gfs2_sbd *sdp)
|
|
||||||
{
|
|
||||||
unsigned int hits, strikes;
|
|
||||||
int error;
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
hits = 0;
|
|
||||||
strikes = 0;
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
struct gfs2_unlinked *ul = ul_fish(sdp);
|
|
||||||
if (!ul)
|
|
||||||
return 0;
|
|
||||||
error = gfs2_inode_dealloc(sdp, ul);
|
|
||||||
gfs2_unlinked_put(sdp, ul);
|
|
||||||
|
|
||||||
if (!error) {
|
|
||||||
hits++;
|
|
||||||
if (strikes)
|
|
||||||
strikes--;
|
|
||||||
} else if (error == 1) {
|
|
||||||
strikes++;
|
|
||||||
if (strikes >=
|
|
||||||
atomic_read(&sdp->sd_unlinked_count)) {
|
|
||||||
error = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hits || kthread_should_stop())
|
|
||||||
break;
|
|
||||||
|
|
||||||
cond_resched();
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int gfs2_unlinked_init(struct gfs2_sbd *sdp)
|
|
||||||
{
|
|
||||||
struct gfs2_inode *ip = sdp->sd_ut_inode->u.generic_ip;
|
|
||||||
unsigned int blocks = ip->i_di.di_size >> sdp->sd_sb.sb_bsize_shift;
|
|
||||||
unsigned int x, slot = 0;
|
|
||||||
unsigned int found = 0;
|
|
||||||
uint64_t dblock;
|
|
||||||
uint32_t extlen = 0;
|
|
||||||
int error;
|
|
||||||
|
|
||||||
if (!ip->i_di.di_size ||
|
|
||||||
ip->i_di.di_size > (64 << 20) ||
|
|
||||||
ip->i_di.di_size & (sdp->sd_sb.sb_bsize - 1)) {
|
|
||||||
gfs2_consist_inode(ip);
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
sdp->sd_unlinked_slots = blocks * sdp->sd_ut_per_block;
|
|
||||||
sdp->sd_unlinked_chunks = DIV_ROUND_UP(sdp->sd_unlinked_slots,
|
|
||||||
8 * PAGE_SIZE);
|
|
||||||
|
|
||||||
error = -ENOMEM;
|
|
||||||
|
|
||||||
sdp->sd_unlinked_bitmap = kcalloc(sdp->sd_unlinked_chunks,
|
|
||||||
sizeof(unsigned char *),
|
|
||||||
GFP_KERNEL);
|
|
||||||
if (!sdp->sd_unlinked_bitmap)
|
|
||||||
return error;
|
|
||||||
|
|
||||||
for (x = 0; x < sdp->sd_unlinked_chunks; x++) {
|
|
||||||
sdp->sd_unlinked_bitmap[x] = kzalloc(PAGE_SIZE, GFP_KERNEL);
|
|
||||||
if (!sdp->sd_unlinked_bitmap[x])
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (x = 0; x < blocks; x++) {
|
|
||||||
struct buffer_head *bh;
|
|
||||||
unsigned int y;
|
|
||||||
|
|
||||||
if (!extlen) {
|
|
||||||
int new = 0;
|
|
||||||
error = gfs2_extent_map(ip->i_vnode, x, &new, &dblock, &extlen);
|
|
||||||
if (error)
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
gfs2_meta_ra(ip->i_gl, dblock, extlen);
|
|
||||||
error = gfs2_meta_read(ip->i_gl, dblock, DIO_START | DIO_WAIT,
|
|
||||||
&bh);
|
|
||||||
if (error)
|
|
||||||
goto fail;
|
|
||||||
error = -EIO;
|
|
||||||
if (gfs2_metatype_check(sdp, bh, GFS2_METATYPE_UT)) {
|
|
||||||
brelse(bh);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (y = 0;
|
|
||||||
y < sdp->sd_ut_per_block && slot < sdp->sd_unlinked_slots;
|
|
||||||
y++, slot++) {
|
|
||||||
struct gfs2_unlinked_tag ut;
|
|
||||||
struct gfs2_unlinked *ul;
|
|
||||||
|
|
||||||
gfs2_unlinked_tag_in(&ut, bh->b_data +
|
|
||||||
sizeof(struct gfs2_meta_header) +
|
|
||||||
y * sizeof(struct gfs2_unlinked_tag));
|
|
||||||
if (!ut.ut_inum.no_addr)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
error = -ENOMEM;
|
|
||||||
ul = ul_alloc(sdp);
|
|
||||||
if (!ul) {
|
|
||||||
brelse(bh);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
ul->ul_ut = ut;
|
|
||||||
ul->ul_slot = slot;
|
|
||||||
|
|
||||||
spin_lock(&sdp->sd_unlinked_spin);
|
|
||||||
gfs2_icbit_munge(sdp, sdp->sd_unlinked_bitmap, slot, 1);
|
|
||||||
spin_unlock(&sdp->sd_unlinked_spin);
|
|
||||||
ul_hash(sdp, ul);
|
|
||||||
|
|
||||||
gfs2_unlinked_put(sdp, ul);
|
|
||||||
found++;
|
|
||||||
}
|
|
||||||
|
|
||||||
brelse(bh);
|
|
||||||
dblock++;
|
|
||||||
extlen--;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found)
|
|
||||||
fs_info(sdp, "found %u unlinked inodes\n", found);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
fail:
|
|
||||||
gfs2_unlinked_cleanup(sdp);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* gfs2_unlinked_cleanup - get rid of any extra struct gfs2_unlinked structures
|
|
||||||
* @sdp: the filesystem
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
void gfs2_unlinked_cleanup(struct gfs2_sbd *sdp)
|
|
||||||
{
|
|
||||||
struct list_head *head = &sdp->sd_unlinked_list;
|
|
||||||
struct gfs2_unlinked *ul;
|
|
||||||
unsigned int x;
|
|
||||||
|
|
||||||
spin_lock(&sdp->sd_unlinked_spin);
|
|
||||||
while (!list_empty(head)) {
|
|
||||||
ul = list_entry(head->next, struct gfs2_unlinked, ul_list);
|
|
||||||
|
|
||||||
if (ul->ul_count > 1) {
|
|
||||||
list_move_tail(&ul->ul_list, head);
|
|
||||||
spin_unlock(&sdp->sd_unlinked_spin);
|
|
||||||
schedule();
|
|
||||||
spin_lock(&sdp->sd_unlinked_spin);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
list_del_init(&ul->ul_list);
|
|
||||||
atomic_dec(&sdp->sd_unlinked_count);
|
|
||||||
|
|
||||||
gfs2_assert_warn(sdp, ul->ul_count == 1);
|
|
||||||
gfs2_assert_warn(sdp, !test_bit(ULF_LOCKED, &ul->ul_flags));
|
|
||||||
kfree(ul);
|
|
||||||
}
|
|
||||||
spin_unlock(&sdp->sd_unlinked_spin);
|
|
||||||
|
|
||||||
gfs2_assert_warn(sdp, !atomic_read(&sdp->sd_unlinked_count));
|
|
||||||
|
|
||||||
if (sdp->sd_unlinked_bitmap) {
|
|
||||||
for (x = 0; x < sdp->sd_unlinked_chunks; x++)
|
|
||||||
kfree(sdp->sd_unlinked_bitmap[x]);
|
|
||||||
kfree(sdp->sd_unlinked_bitmap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
|
|
||||||
* Copyright (C) 2004-2006 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
|
|
||||||
* of the GNU General Public License v.2.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __UNLINKED_DOT_H__
|
|
||||||
#define __UNLINKED_DOT_H__
|
|
||||||
|
|
||||||
int gfs2_unlinked_get(struct gfs2_sbd *sdp, struct gfs2_unlinked **ul);
|
|
||||||
void gfs2_unlinked_put(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul);
|
|
||||||
|
|
||||||
int gfs2_unlinked_ondisk_add(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul);
|
|
||||||
int gfs2_unlinked_ondisk_munge(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul);
|
|
||||||
int gfs2_unlinked_ondisk_rm(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul);
|
|
||||||
|
|
||||||
int gfs2_unlinked_dealloc(struct gfs2_sbd *sdp);
|
|
||||||
|
|
||||||
int gfs2_unlinked_init(struct gfs2_sbd *sdp);
|
|
||||||
void gfs2_unlinked_cleanup(struct gfs2_sbd *sdp);
|
|
||||||
|
|
||||||
#endif /* __UNLINKED_DOT_H__ */
|
|
|
@ -109,7 +109,7 @@ int gfs2_consist_i(struct gfs2_sbd *sdp, int cluster_wide, const char *function,
|
||||||
int gfs2_consist_inode_i(struct gfs2_inode *ip, int cluster_wide,
|
int gfs2_consist_inode_i(struct gfs2_inode *ip, int cluster_wide,
|
||||||
const char *function, char *file, unsigned int line)
|
const char *function, char *file, unsigned int line)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = ip->i_sbd;
|
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
||||||
int rv;
|
int rv;
|
||||||
rv = gfs2_lm_withdraw(sdp,
|
rv = gfs2_lm_withdraw(sdp,
|
||||||
"GFS2: fsid=%s: fatal: filesystem consistency error\n"
|
"GFS2: fsid=%s: fatal: filesystem consistency error\n"
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
|
* Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
|
||||||
* Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
|
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* This copyrighted material is made available to anyone wishing to use,
|
* This copyrighted material is made available to anyone wishing to use,
|
||||||
* modify, copy, or redistribute it subject to the terms and conditions
|
* modify, copy, or redistribute it subject to the terms and conditions
|
||||||
* of the GNU General Public License v.2.
|
* of the GNU General Public License v.2.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __GFS2_ONDISK_DOT_H__
|
#ifndef __GFS2_ONDISK_DOT_H__
|
||||||
#define __GFS2_ONDISK_DOT_H__
|
#define __GFS2_ONDISK_DOT_H__
|
||||||
|
@ -36,7 +36,6 @@
|
||||||
#define GFS2_FORMAT_LB 1000
|
#define GFS2_FORMAT_LB 1000
|
||||||
#define GFS2_FORMAT_EA 1600
|
#define GFS2_FORMAT_EA 1600
|
||||||
#define GFS2_FORMAT_ED 1700
|
#define GFS2_FORMAT_ED 1700
|
||||||
#define GFS2_FORMAT_UT 1300
|
|
||||||
#define GFS2_FORMAT_QC 1400
|
#define GFS2_FORMAT_QC 1400
|
||||||
/* These are format numbers for entities contained in files */
|
/* These are format numbers for entities contained in files */
|
||||||
#define GFS2_FORMAT_RI 1100
|
#define GFS2_FORMAT_RI 1100
|
||||||
|
@ -80,7 +79,6 @@ static inline int gfs2_inum_equal(const struct gfs2_inum *ino1,
|
||||||
#define GFS2_METATYPE_LB 12
|
#define GFS2_METATYPE_LB 12
|
||||||
#define GFS2_METATYPE_EA 10
|
#define GFS2_METATYPE_EA 10
|
||||||
#define GFS2_METATYPE_ED 11
|
#define GFS2_METATYPE_ED 11
|
||||||
#define GFS2_METATYPE_UT 13
|
|
||||||
#define GFS2_METATYPE_QC 14
|
#define GFS2_METATYPE_QC 14
|
||||||
|
|
||||||
struct gfs2_meta_header {
|
struct gfs2_meta_header {
|
||||||
|
@ -158,7 +156,7 @@ struct gfs2_rindex {
|
||||||
|
|
||||||
#define GFS2_BLKST_FREE 0
|
#define GFS2_BLKST_FREE 0
|
||||||
#define GFS2_BLKST_USED 1
|
#define GFS2_BLKST_USED 1
|
||||||
#define GFS2_BLKST_INVALID 2
|
#define GFS2_BLKST_UNLINKED 2
|
||||||
#define GFS2_BLKST_DINODE 3
|
#define GFS2_BLKST_DINODE 3
|
||||||
|
|
||||||
#define GFS2_RGF_JOURNAL 0x00000001
|
#define GFS2_RGF_JOURNAL 0x00000001
|
||||||
|
@ -396,20 +394,6 @@ struct gfs2_statfs_change {
|
||||||
__be64 sc_dinodes;
|
__be64 sc_dinodes;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* Unlinked Tag
|
|
||||||
* Describes an allocated inode that isn't linked into
|
|
||||||
* the directory tree and might need to be deallocated.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define GFS2_UTF_UNINIT 0x00000001
|
|
||||||
|
|
||||||
struct gfs2_unlinked_tag {
|
|
||||||
struct gfs2_inum ut_inum;
|
|
||||||
__be32 ut_flags; /* GFS2_UTF_... */
|
|
||||||
__u32 __pad;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Quota change
|
* Quota change
|
||||||
* Describes an allocation change for a particular
|
* Describes an allocation change for a particular
|
||||||
|
@ -445,8 +429,6 @@ extern void gfs2_inum_range_in(struct gfs2_inum_range *ir, char *buf);
|
||||||
extern void gfs2_inum_range_out(struct gfs2_inum_range *ir, char *buf);
|
extern void gfs2_inum_range_out(struct gfs2_inum_range *ir, char *buf);
|
||||||
extern void gfs2_statfs_change_in(struct gfs2_statfs_change *sc, char *buf);
|
extern void gfs2_statfs_change_in(struct gfs2_statfs_change *sc, char *buf);
|
||||||
extern void gfs2_statfs_change_out(struct gfs2_statfs_change *sc, char *buf);
|
extern void gfs2_statfs_change_out(struct gfs2_statfs_change *sc, char *buf);
|
||||||
extern void gfs2_unlinked_tag_in(struct gfs2_unlinked_tag *ut, char *buf);
|
|
||||||
extern void gfs2_unlinked_tag_out(struct gfs2_unlinked_tag *ut, char *buf);
|
|
||||||
extern void gfs2_quota_change_in(struct gfs2_quota_change *qc, char *buf);
|
extern void gfs2_quota_change_in(struct gfs2_quota_change *qc, char *buf);
|
||||||
|
|
||||||
/* Printing functions */
|
/* Printing functions */
|
||||||
|
|
Loading…
Reference in New Issue