mirror of
https://github.com/torvalds/linux.git
synced 2024-11-02 02:01:29 +00:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-nmw
* git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-nmw: GFS2: print glock numbers in hex GFS2: ordered writes are backwards GFS2: Remove old, unused linked list code from quota GFS2: Remove loopy umount code GFS2: Metadata address space clean up
This commit is contained in:
commit
4850f524b2
@ -1061,8 +1061,8 @@ out:
|
|||||||
|
|
||||||
int gfs2_releasepage(struct page *page, gfp_t gfp_mask)
|
int gfs2_releasepage(struct page *page, gfp_t gfp_mask)
|
||||||
{
|
{
|
||||||
struct inode *aspace = page->mapping->host;
|
struct address_space *mapping = page->mapping;
|
||||||
struct gfs2_sbd *sdp = aspace->i_sb->s_fs_info;
|
struct gfs2_sbd *sdp = gfs2_mapping2sbd(mapping);
|
||||||
struct buffer_head *bh, *head;
|
struct buffer_head *bh, *head;
|
||||||
struct gfs2_bufdata *bd;
|
struct gfs2_bufdata *bd;
|
||||||
|
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
#include <linux/wait.h>
|
#include <linux/wait.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/rwsem.h>
|
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
#include <linux/seq_file.h>
|
#include <linux/seq_file.h>
|
||||||
#include <linux/debugfs.h>
|
#include <linux/debugfs.h>
|
||||||
@ -60,7 +59,6 @@ static int __dump_glock(struct seq_file *seq, const struct gfs2_glock *gl);
|
|||||||
#define GLOCK_BUG_ON(gl,x) do { if (unlikely(x)) { __dump_glock(NULL, gl); BUG(); } } while(0)
|
#define GLOCK_BUG_ON(gl,x) do { if (unlikely(x)) { __dump_glock(NULL, gl); BUG(); } } while(0)
|
||||||
static void do_xmote(struct gfs2_glock *gl, struct gfs2_holder *gh, unsigned int target);
|
static void do_xmote(struct gfs2_glock *gl, struct gfs2_holder *gh, unsigned int target);
|
||||||
|
|
||||||
static DECLARE_RWSEM(gfs2_umount_flush_sem);
|
|
||||||
static struct dentry *gfs2_root;
|
static struct dentry *gfs2_root;
|
||||||
static struct workqueue_struct *glock_workqueue;
|
static struct workqueue_struct *glock_workqueue;
|
||||||
struct workqueue_struct *gfs2_delete_workqueue;
|
struct workqueue_struct *gfs2_delete_workqueue;
|
||||||
@ -154,12 +152,14 @@ static unsigned int gl_hash(const struct gfs2_sbd *sdp,
|
|||||||
static void glock_free(struct gfs2_glock *gl)
|
static void glock_free(struct gfs2_glock *gl)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = gl->gl_sbd;
|
struct gfs2_sbd *sdp = gl->gl_sbd;
|
||||||
struct inode *aspace = gl->gl_aspace;
|
struct address_space *mapping = gfs2_glock2aspace(gl);
|
||||||
|
struct kmem_cache *cachep = gfs2_glock_cachep;
|
||||||
|
|
||||||
if (aspace)
|
GLOCK_BUG_ON(gl, mapping && mapping->nrpages);
|
||||||
gfs2_aspace_put(aspace);
|
|
||||||
trace_gfs2_glock_put(gl);
|
trace_gfs2_glock_put(gl);
|
||||||
sdp->sd_lockstruct.ls_ops->lm_put_lock(gfs2_glock_cachep, gl);
|
if (mapping)
|
||||||
|
cachep = gfs2_glock_aspace_cachep;
|
||||||
|
sdp->sd_lockstruct.ls_ops->lm_put_lock(cachep, gl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -712,7 +712,6 @@ static void glock_work_func(struct work_struct *work)
|
|||||||
finish_xmote(gl, gl->gl_reply);
|
finish_xmote(gl, gl->gl_reply);
|
||||||
drop_ref = 1;
|
drop_ref = 1;
|
||||||
}
|
}
|
||||||
down_read(&gfs2_umount_flush_sem);
|
|
||||||
spin_lock(&gl->gl_spin);
|
spin_lock(&gl->gl_spin);
|
||||||
if (test_and_clear_bit(GLF_PENDING_DEMOTE, &gl->gl_flags) &&
|
if (test_and_clear_bit(GLF_PENDING_DEMOTE, &gl->gl_flags) &&
|
||||||
gl->gl_state != LM_ST_UNLOCKED &&
|
gl->gl_state != LM_ST_UNLOCKED &&
|
||||||
@ -725,7 +724,6 @@ static void glock_work_func(struct work_struct *work)
|
|||||||
}
|
}
|
||||||
run_queue(gl, 0);
|
run_queue(gl, 0);
|
||||||
spin_unlock(&gl->gl_spin);
|
spin_unlock(&gl->gl_spin);
|
||||||
up_read(&gfs2_umount_flush_sem);
|
|
||||||
if (!delay ||
|
if (!delay ||
|
||||||
queue_delayed_work(glock_workqueue, &gl->gl_work, delay) == 0)
|
queue_delayed_work(glock_workqueue, &gl->gl_work, delay) == 0)
|
||||||
gfs2_glock_put(gl);
|
gfs2_glock_put(gl);
|
||||||
@ -750,10 +748,11 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
|
|||||||
const struct gfs2_glock_operations *glops, int create,
|
const struct gfs2_glock_operations *glops, int create,
|
||||||
struct gfs2_glock **glp)
|
struct gfs2_glock **glp)
|
||||||
{
|
{
|
||||||
|
struct super_block *s = sdp->sd_vfs;
|
||||||
struct lm_lockname name = { .ln_number = number, .ln_type = glops->go_type };
|
struct lm_lockname name = { .ln_number = number, .ln_type = glops->go_type };
|
||||||
struct gfs2_glock *gl, *tmp;
|
struct gfs2_glock *gl, *tmp;
|
||||||
unsigned int hash = gl_hash(sdp, &name);
|
unsigned int hash = gl_hash(sdp, &name);
|
||||||
int error;
|
struct address_space *mapping;
|
||||||
|
|
||||||
read_lock(gl_lock_addr(hash));
|
read_lock(gl_lock_addr(hash));
|
||||||
gl = search_bucket(hash, sdp, &name);
|
gl = search_bucket(hash, sdp, &name);
|
||||||
@ -765,7 +764,10 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
|
|||||||
if (!create)
|
if (!create)
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
gl = kmem_cache_alloc(gfs2_glock_cachep, GFP_KERNEL);
|
if (glops->go_flags & GLOF_ASPACE)
|
||||||
|
gl = kmem_cache_alloc(gfs2_glock_aspace_cachep, GFP_KERNEL);
|
||||||
|
else
|
||||||
|
gl = kmem_cache_alloc(gfs2_glock_cachep, GFP_KERNEL);
|
||||||
if (!gl)
|
if (!gl)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
@ -784,18 +786,18 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
|
|||||||
gl->gl_tchange = jiffies;
|
gl->gl_tchange = jiffies;
|
||||||
gl->gl_object = NULL;
|
gl->gl_object = NULL;
|
||||||
gl->gl_sbd = sdp;
|
gl->gl_sbd = sdp;
|
||||||
gl->gl_aspace = NULL;
|
|
||||||
INIT_DELAYED_WORK(&gl->gl_work, glock_work_func);
|
INIT_DELAYED_WORK(&gl->gl_work, glock_work_func);
|
||||||
INIT_WORK(&gl->gl_delete, delete_work_func);
|
INIT_WORK(&gl->gl_delete, delete_work_func);
|
||||||
|
|
||||||
/* If this glock protects actual on-disk data or metadata blocks,
|
mapping = gfs2_glock2aspace(gl);
|
||||||
create a VFS inode to manage the pages/buffers holding them. */
|
if (mapping) {
|
||||||
if (glops == &gfs2_inode_glops || glops == &gfs2_rgrp_glops) {
|
mapping->a_ops = &gfs2_meta_aops;
|
||||||
gl->gl_aspace = gfs2_aspace_get(sdp);
|
mapping->host = s->s_bdev->bd_inode;
|
||||||
if (!gl->gl_aspace) {
|
mapping->flags = 0;
|
||||||
error = -ENOMEM;
|
mapping_set_gfp_mask(mapping, GFP_NOFS);
|
||||||
goto fail;
|
mapping->assoc_mapping = NULL;
|
||||||
}
|
mapping->backing_dev_info = s->s_bdi;
|
||||||
|
mapping->writeback_index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
write_lock(gl_lock_addr(hash));
|
write_lock(gl_lock_addr(hash));
|
||||||
@ -812,10 +814,6 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
|
|||||||
*glp = gl;
|
*glp = gl;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail:
|
|
||||||
kmem_cache_free(gfs2_glock_cachep, gl);
|
|
||||||
return error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1510,35 +1508,10 @@ void gfs2_glock_thaw(struct gfs2_sbd *sdp)
|
|||||||
|
|
||||||
void gfs2_gl_hash_clear(struct gfs2_sbd *sdp)
|
void gfs2_gl_hash_clear(struct gfs2_sbd *sdp)
|
||||||
{
|
{
|
||||||
unsigned long t;
|
|
||||||
unsigned int x;
|
unsigned int x;
|
||||||
int cont;
|
|
||||||
|
|
||||||
t = jiffies;
|
for (x = 0; x < GFS2_GL_HASH_SIZE; x++)
|
||||||
|
examine_bucket(clear_glock, sdp, x);
|
||||||
for (;;) {
|
|
||||||
cont = 0;
|
|
||||||
for (x = 0; x < GFS2_GL_HASH_SIZE; x++) {
|
|
||||||
if (examine_bucket(clear_glock, sdp, x))
|
|
||||||
cont = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!cont)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (time_after_eq(jiffies,
|
|
||||||
t + gfs2_tune_get(sdp, gt_stall_secs) * HZ)) {
|
|
||||||
fs_warn(sdp, "Unmount seems to be stalled. "
|
|
||||||
"Dumping lock state...\n");
|
|
||||||
gfs2_dump_lockstate(sdp);
|
|
||||||
t = jiffies;
|
|
||||||
}
|
|
||||||
|
|
||||||
down_write(&gfs2_umount_flush_sem);
|
|
||||||
invalidate_inodes(sdp->sd_vfs);
|
|
||||||
up_write(&gfs2_umount_flush_sem);
|
|
||||||
msleep(10);
|
|
||||||
}
|
|
||||||
flush_workqueue(glock_workqueue);
|
flush_workqueue(glock_workqueue);
|
||||||
wait_event(sdp->sd_glock_wait, atomic_read(&sdp->sd_glock_disposal) == 0);
|
wait_event(sdp->sd_glock_wait, atomic_read(&sdp->sd_glock_disposal) == 0);
|
||||||
gfs2_dump_lockstate(sdp);
|
gfs2_dump_lockstate(sdp);
|
||||||
@ -1685,7 +1658,7 @@ static int __dump_glock(struct seq_file *seq, const struct gfs2_glock *gl)
|
|||||||
dtime *= 1000000/HZ; /* demote time in uSec */
|
dtime *= 1000000/HZ; /* demote time in uSec */
|
||||||
if (!test_bit(GLF_DEMOTE, &gl->gl_flags))
|
if (!test_bit(GLF_DEMOTE, &gl->gl_flags))
|
||||||
dtime = 0;
|
dtime = 0;
|
||||||
gfs2_print_dbg(seq, "G: s:%s n:%u/%llu f:%s t:%s d:%s/%llu a:%d r:%d\n",
|
gfs2_print_dbg(seq, "G: s:%s n:%u/%llx f:%s t:%s d:%s/%llu a:%d r:%d\n",
|
||||||
state2str(gl->gl_state),
|
state2str(gl->gl_state),
|
||||||
gl->gl_name.ln_type,
|
gl->gl_name.ln_type,
|
||||||
(unsigned long long)gl->gl_name.ln_number,
|
(unsigned long long)gl->gl_name.ln_number,
|
||||||
|
@ -180,6 +180,13 @@ static inline int gfs2_glock_is_held_shrd(struct gfs2_glock *gl)
|
|||||||
return gl->gl_state == LM_ST_SHARED;
|
return gl->gl_state == LM_ST_SHARED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline struct address_space *gfs2_glock2aspace(struct gfs2_glock *gl)
|
||||||
|
{
|
||||||
|
if (gl->gl_ops->go_flags & GLOF_ASPACE)
|
||||||
|
return (struct address_space *)(gl + 1);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
int gfs2_glock_get(struct gfs2_sbd *sdp,
|
int gfs2_glock_get(struct gfs2_sbd *sdp,
|
||||||
u64 number, const struct gfs2_glock_operations *glops,
|
u64 number, const struct gfs2_glock_operations *glops,
|
||||||
int create, struct gfs2_glock **glp);
|
int create, struct gfs2_glock **glp);
|
||||||
|
@ -87,7 +87,7 @@ static void gfs2_ail_empty_gl(struct gfs2_glock *gl)
|
|||||||
|
|
||||||
static void rgrp_go_sync(struct gfs2_glock *gl)
|
static void rgrp_go_sync(struct gfs2_glock *gl)
|
||||||
{
|
{
|
||||||
struct address_space *metamapping = gl->gl_aspace->i_mapping;
|
struct address_space *metamapping = gfs2_glock2aspace(gl);
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
if (!test_and_clear_bit(GLF_DIRTY, &gl->gl_flags))
|
if (!test_and_clear_bit(GLF_DIRTY, &gl->gl_flags))
|
||||||
@ -113,7 +113,7 @@ static void rgrp_go_sync(struct gfs2_glock *gl)
|
|||||||
|
|
||||||
static void rgrp_go_inval(struct gfs2_glock *gl, int flags)
|
static void rgrp_go_inval(struct gfs2_glock *gl, int flags)
|
||||||
{
|
{
|
||||||
struct address_space *mapping = gl->gl_aspace->i_mapping;
|
struct address_space *mapping = gfs2_glock2aspace(gl);
|
||||||
|
|
||||||
BUG_ON(!(flags & DIO_METADATA));
|
BUG_ON(!(flags & DIO_METADATA));
|
||||||
gfs2_assert_withdraw(gl->gl_sbd, !atomic_read(&gl->gl_ail_count));
|
gfs2_assert_withdraw(gl->gl_sbd, !atomic_read(&gl->gl_ail_count));
|
||||||
@ -134,7 +134,7 @@ static void rgrp_go_inval(struct gfs2_glock *gl, int flags)
|
|||||||
static void inode_go_sync(struct gfs2_glock *gl)
|
static void inode_go_sync(struct gfs2_glock *gl)
|
||||||
{
|
{
|
||||||
struct gfs2_inode *ip = gl->gl_object;
|
struct gfs2_inode *ip = gl->gl_object;
|
||||||
struct address_space *metamapping = gl->gl_aspace->i_mapping;
|
struct address_space *metamapping = gfs2_glock2aspace(gl);
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
if (ip && !S_ISREG(ip->i_inode.i_mode))
|
if (ip && !S_ISREG(ip->i_inode.i_mode))
|
||||||
@ -183,7 +183,7 @@ static void inode_go_inval(struct gfs2_glock *gl, int flags)
|
|||||||
gfs2_assert_withdraw(gl->gl_sbd, !atomic_read(&gl->gl_ail_count));
|
gfs2_assert_withdraw(gl->gl_sbd, !atomic_read(&gl->gl_ail_count));
|
||||||
|
|
||||||
if (flags & DIO_METADATA) {
|
if (flags & DIO_METADATA) {
|
||||||
struct address_space *mapping = gl->gl_aspace->i_mapping;
|
struct address_space *mapping = gfs2_glock2aspace(gl);
|
||||||
truncate_inode_pages(mapping, 0);
|
truncate_inode_pages(mapping, 0);
|
||||||
if (ip) {
|
if (ip) {
|
||||||
set_bit(GIF_INVALID, &ip->i_flags);
|
set_bit(GIF_INVALID, &ip->i_flags);
|
||||||
@ -282,7 +282,8 @@ static int inode_go_dump(struct seq_file *seq, const struct gfs2_glock *gl)
|
|||||||
|
|
||||||
static int rgrp_go_demote_ok(const struct gfs2_glock *gl)
|
static int rgrp_go_demote_ok(const struct gfs2_glock *gl)
|
||||||
{
|
{
|
||||||
return !gl->gl_aspace->i_mapping->nrpages;
|
const struct address_space *mapping = (const struct address_space *)(gl + 1);
|
||||||
|
return !mapping->nrpages;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -387,8 +388,7 @@ static void iopen_go_callback(struct gfs2_glock *gl)
|
|||||||
struct gfs2_inode *ip = (struct gfs2_inode *)gl->gl_object;
|
struct gfs2_inode *ip = (struct gfs2_inode *)gl->gl_object;
|
||||||
|
|
||||||
if (gl->gl_demote_state == LM_ST_UNLOCKED &&
|
if (gl->gl_demote_state == LM_ST_UNLOCKED &&
|
||||||
gl->gl_state == LM_ST_SHARED &&
|
gl->gl_state == LM_ST_SHARED && ip) {
|
||||||
ip && test_bit(GIF_USER, &ip->i_flags)) {
|
|
||||||
gfs2_glock_hold(gl);
|
gfs2_glock_hold(gl);
|
||||||
if (queue_work(gfs2_delete_workqueue, &gl->gl_delete) == 0)
|
if (queue_work(gfs2_delete_workqueue, &gl->gl_delete) == 0)
|
||||||
gfs2_glock_put_nolock(gl);
|
gfs2_glock_put_nolock(gl);
|
||||||
@ -407,6 +407,7 @@ const struct gfs2_glock_operations gfs2_inode_glops = {
|
|||||||
.go_dump = inode_go_dump,
|
.go_dump = inode_go_dump,
|
||||||
.go_type = LM_TYPE_INODE,
|
.go_type = LM_TYPE_INODE,
|
||||||
.go_min_hold_time = HZ / 5,
|
.go_min_hold_time = HZ / 5,
|
||||||
|
.go_flags = GLOF_ASPACE,
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct gfs2_glock_operations gfs2_rgrp_glops = {
|
const struct gfs2_glock_operations gfs2_rgrp_glops = {
|
||||||
@ -418,6 +419,7 @@ const struct gfs2_glock_operations gfs2_rgrp_glops = {
|
|||||||
.go_dump = gfs2_rgrp_dump,
|
.go_dump = gfs2_rgrp_dump,
|
||||||
.go_type = LM_TYPE_RGRP,
|
.go_type = LM_TYPE_RGRP,
|
||||||
.go_min_hold_time = HZ / 5,
|
.go_min_hold_time = HZ / 5,
|
||||||
|
.go_flags = GLOF_ASPACE,
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct gfs2_glock_operations gfs2_trans_glops = {
|
const struct gfs2_glock_operations gfs2_trans_glops = {
|
||||||
|
@ -162,6 +162,8 @@ struct gfs2_glock_operations {
|
|||||||
void (*go_callback) (struct gfs2_glock *gl);
|
void (*go_callback) (struct gfs2_glock *gl);
|
||||||
const int go_type;
|
const int go_type;
|
||||||
const unsigned long go_min_hold_time;
|
const unsigned long go_min_hold_time;
|
||||||
|
const unsigned long go_flags;
|
||||||
|
#define GLOF_ASPACE 1
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@ -225,7 +227,6 @@ struct gfs2_glock {
|
|||||||
|
|
||||||
struct gfs2_sbd *gl_sbd;
|
struct gfs2_sbd *gl_sbd;
|
||||||
|
|
||||||
struct inode *gl_aspace;
|
|
||||||
struct list_head gl_ail_list;
|
struct list_head gl_ail_list;
|
||||||
atomic_t gl_ail_count;
|
atomic_t gl_ail_count;
|
||||||
struct delayed_work gl_work;
|
struct delayed_work gl_work;
|
||||||
@ -258,7 +259,6 @@ enum {
|
|||||||
GIF_INVALID = 0,
|
GIF_INVALID = 0,
|
||||||
GIF_QD_LOCKED = 1,
|
GIF_QD_LOCKED = 1,
|
||||||
GIF_SW_PAGED = 3,
|
GIF_SW_PAGED = 3,
|
||||||
GIF_USER = 4, /* user inode, not metadata addr space */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -451,7 +451,6 @@ struct gfs2_tune {
|
|||||||
unsigned int gt_quota_quantum; /* Secs between syncs to quota file */
|
unsigned int gt_quota_quantum; /* Secs between syncs to quota file */
|
||||||
unsigned int gt_new_files_jdata;
|
unsigned int gt_new_files_jdata;
|
||||||
unsigned int gt_max_readahead; /* Max bytes to read-ahead from disk */
|
unsigned int gt_max_readahead; /* Max bytes to read-ahead from disk */
|
||||||
unsigned int gt_stall_secs; /* Detects trouble! */
|
|
||||||
unsigned int gt_complain_secs;
|
unsigned int gt_complain_secs;
|
||||||
unsigned int gt_statfs_quantum;
|
unsigned int gt_statfs_quantum;
|
||||||
unsigned int gt_statfs_slow;
|
unsigned int gt_statfs_slow;
|
||||||
|
@ -45,7 +45,7 @@ static int iget_test(struct inode *inode, void *opaque)
|
|||||||
struct gfs2_inode *ip = GFS2_I(inode);
|
struct gfs2_inode *ip = GFS2_I(inode);
|
||||||
u64 *no_addr = opaque;
|
u64 *no_addr = opaque;
|
||||||
|
|
||||||
if (ip->i_no_addr == *no_addr && test_bit(GIF_USER, &ip->i_flags))
|
if (ip->i_no_addr == *no_addr)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -58,7 +58,6 @@ static int iget_set(struct inode *inode, void *opaque)
|
|||||||
|
|
||||||
inode->i_ino = (unsigned long)*no_addr;
|
inode->i_ino = (unsigned long)*no_addr;
|
||||||
ip->i_no_addr = *no_addr;
|
ip->i_no_addr = *no_addr;
|
||||||
set_bit(GIF_USER, &ip->i_flags);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,7 +83,7 @@ static int iget_skip_test(struct inode *inode, void *opaque)
|
|||||||
struct gfs2_inode *ip = GFS2_I(inode);
|
struct gfs2_inode *ip = GFS2_I(inode);
|
||||||
struct gfs2_skip_data *data = opaque;
|
struct gfs2_skip_data *data = opaque;
|
||||||
|
|
||||||
if (ip->i_no_addr == data->no_addr && test_bit(GIF_USER, &ip->i_flags)){
|
if (ip->i_no_addr == data->no_addr) {
|
||||||
if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE)){
|
if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE)){
|
||||||
data->skipped = 1;
|
data->skipped = 1;
|
||||||
return 0;
|
return 0;
|
||||||
@ -103,7 +102,6 @@ static int iget_skip_set(struct inode *inode, void *opaque)
|
|||||||
return 1;
|
return 1;
|
||||||
inode->i_ino = (unsigned long)(data->no_addr);
|
inode->i_ino = (unsigned long)(data->no_addr);
|
||||||
ip->i_no_addr = data->no_addr;
|
ip->i_no_addr = data->no_addr;
|
||||||
set_bit(GIF_USER, &ip->i_flags);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +30,10 @@ static void gdlm_ast(void *arg)
|
|||||||
|
|
||||||
switch (gl->gl_lksb.sb_status) {
|
switch (gl->gl_lksb.sb_status) {
|
||||||
case -DLM_EUNLOCK: /* Unlocked, so glock can be freed */
|
case -DLM_EUNLOCK: /* Unlocked, so glock can be freed */
|
||||||
kmem_cache_free(gfs2_glock_cachep, gl);
|
if (gl->gl_ops->go_flags & GLOF_ASPACE)
|
||||||
|
kmem_cache_free(gfs2_glock_aspace_cachep, gl);
|
||||||
|
else
|
||||||
|
kmem_cache_free(gfs2_glock_cachep, gl);
|
||||||
if (atomic_dec_and_test(&sdp->sd_glock_disposal))
|
if (atomic_dec_and_test(&sdp->sd_glock_disposal))
|
||||||
wake_up(&sdp->sd_glock_wait);
|
wake_up(&sdp->sd_glock_wait);
|
||||||
return;
|
return;
|
||||||
|
@ -528,9 +528,9 @@ static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le)
|
|||||||
gfs2_pin(sdp, bd->bd_bh);
|
gfs2_pin(sdp, bd->bd_bh);
|
||||||
tr->tr_num_databuf_new++;
|
tr->tr_num_databuf_new++;
|
||||||
sdp->sd_log_num_databuf++;
|
sdp->sd_log_num_databuf++;
|
||||||
list_add(&le->le_list, &sdp->sd_log_le_databuf);
|
list_add_tail(&le->le_list, &sdp->sd_log_le_databuf);
|
||||||
} else {
|
} else {
|
||||||
list_add(&le->le_list, &sdp->sd_log_le_ordered);
|
list_add_tail(&le->le_list, &sdp->sd_log_le_ordered);
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
gfs2_log_unlock(sdp);
|
gfs2_log_unlock(sdp);
|
||||||
|
@ -52,6 +52,22 @@ static void gfs2_init_glock_once(void *foo)
|
|||||||
atomic_set(&gl->gl_ail_count, 0);
|
atomic_set(&gl->gl_ail_count, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void gfs2_init_gl_aspace_once(void *foo)
|
||||||
|
{
|
||||||
|
struct gfs2_glock *gl = foo;
|
||||||
|
struct address_space *mapping = (struct address_space *)(gl + 1);
|
||||||
|
|
||||||
|
gfs2_init_glock_once(gl);
|
||||||
|
memset(mapping, 0, sizeof(*mapping));
|
||||||
|
INIT_RADIX_TREE(&mapping->page_tree, GFP_ATOMIC);
|
||||||
|
spin_lock_init(&mapping->tree_lock);
|
||||||
|
spin_lock_init(&mapping->i_mmap_lock);
|
||||||
|
INIT_LIST_HEAD(&mapping->private_list);
|
||||||
|
spin_lock_init(&mapping->private_lock);
|
||||||
|
INIT_RAW_PRIO_TREE_ROOT(&mapping->i_mmap);
|
||||||
|
INIT_LIST_HEAD(&mapping->i_mmap_nonlinear);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* init_gfs2_fs - Register GFS2 as a filesystem
|
* init_gfs2_fs - Register GFS2 as a filesystem
|
||||||
*
|
*
|
||||||
@ -78,6 +94,14 @@ static int __init init_gfs2_fs(void)
|
|||||||
if (!gfs2_glock_cachep)
|
if (!gfs2_glock_cachep)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
gfs2_glock_aspace_cachep = kmem_cache_create("gfs2_glock (aspace)",
|
||||||
|
sizeof(struct gfs2_glock) +
|
||||||
|
sizeof(struct address_space),
|
||||||
|
0, 0, gfs2_init_gl_aspace_once);
|
||||||
|
|
||||||
|
if (!gfs2_glock_aspace_cachep)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
gfs2_inode_cachep = kmem_cache_create("gfs2_inode",
|
gfs2_inode_cachep = kmem_cache_create("gfs2_inode",
|
||||||
sizeof(struct gfs2_inode),
|
sizeof(struct gfs2_inode),
|
||||||
0, SLAB_RECLAIM_ACCOUNT|
|
0, SLAB_RECLAIM_ACCOUNT|
|
||||||
@ -144,6 +168,9 @@ fail:
|
|||||||
if (gfs2_inode_cachep)
|
if (gfs2_inode_cachep)
|
||||||
kmem_cache_destroy(gfs2_inode_cachep);
|
kmem_cache_destroy(gfs2_inode_cachep);
|
||||||
|
|
||||||
|
if (gfs2_glock_aspace_cachep)
|
||||||
|
kmem_cache_destroy(gfs2_glock_aspace_cachep);
|
||||||
|
|
||||||
if (gfs2_glock_cachep)
|
if (gfs2_glock_cachep)
|
||||||
kmem_cache_destroy(gfs2_glock_cachep);
|
kmem_cache_destroy(gfs2_glock_cachep);
|
||||||
|
|
||||||
@ -169,6 +196,7 @@ static void __exit exit_gfs2_fs(void)
|
|||||||
kmem_cache_destroy(gfs2_rgrpd_cachep);
|
kmem_cache_destroy(gfs2_rgrpd_cachep);
|
||||||
kmem_cache_destroy(gfs2_bufdata_cachep);
|
kmem_cache_destroy(gfs2_bufdata_cachep);
|
||||||
kmem_cache_destroy(gfs2_inode_cachep);
|
kmem_cache_destroy(gfs2_inode_cachep);
|
||||||
|
kmem_cache_destroy(gfs2_glock_aspace_cachep);
|
||||||
kmem_cache_destroy(gfs2_glock_cachep);
|
kmem_cache_destroy(gfs2_glock_cachep);
|
||||||
|
|
||||||
gfs2_sys_uninit();
|
gfs2_sys_uninit();
|
||||||
|
@ -93,48 +93,12 @@ static int gfs2_aspace_writepage(struct page *page, struct writeback_control *wb
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct address_space_operations aspace_aops = {
|
const struct address_space_operations gfs2_meta_aops = {
|
||||||
.writepage = gfs2_aspace_writepage,
|
.writepage = gfs2_aspace_writepage,
|
||||||
.releasepage = gfs2_releasepage,
|
.releasepage = gfs2_releasepage,
|
||||||
.sync_page = block_sync_page,
|
.sync_page = block_sync_page,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* gfs2_aspace_get - Create and initialize a struct inode structure
|
|
||||||
* @sdp: the filesystem the aspace is in
|
|
||||||
*
|
|
||||||
* Right now a struct inode is just a struct inode. Maybe Linux
|
|
||||||
* will supply a more lightweight address space construct (that works)
|
|
||||||
* in the future.
|
|
||||||
*
|
|
||||||
* Make sure pages/buffers in this aspace aren't in high memory.
|
|
||||||
*
|
|
||||||
* Returns: the aspace
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct inode *gfs2_aspace_get(struct gfs2_sbd *sdp)
|
|
||||||
{
|
|
||||||
struct inode *aspace;
|
|
||||||
struct gfs2_inode *ip;
|
|
||||||
|
|
||||||
aspace = new_inode(sdp->sd_vfs);
|
|
||||||
if (aspace) {
|
|
||||||
mapping_set_gfp_mask(aspace->i_mapping, GFP_NOFS);
|
|
||||||
aspace->i_mapping->a_ops = &aspace_aops;
|
|
||||||
aspace->i_size = MAX_LFS_FILESIZE;
|
|
||||||
ip = GFS2_I(aspace);
|
|
||||||
clear_bit(GIF_USER, &ip->i_flags);
|
|
||||||
insert_inode_hash(aspace);
|
|
||||||
}
|
|
||||||
return aspace;
|
|
||||||
}
|
|
||||||
|
|
||||||
void gfs2_aspace_put(struct inode *aspace)
|
|
||||||
{
|
|
||||||
remove_inode_hash(aspace);
|
|
||||||
iput(aspace);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gfs2_meta_sync - Sync all buffers associated with a glock
|
* gfs2_meta_sync - Sync all buffers associated with a glock
|
||||||
* @gl: The glock
|
* @gl: The glock
|
||||||
@ -143,7 +107,7 @@ void gfs2_aspace_put(struct inode *aspace)
|
|||||||
|
|
||||||
void gfs2_meta_sync(struct gfs2_glock *gl)
|
void gfs2_meta_sync(struct gfs2_glock *gl)
|
||||||
{
|
{
|
||||||
struct address_space *mapping = gl->gl_aspace->i_mapping;
|
struct address_space *mapping = gfs2_glock2aspace(gl);
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
filemap_fdatawrite(mapping);
|
filemap_fdatawrite(mapping);
|
||||||
@ -164,7 +128,7 @@ void gfs2_meta_sync(struct gfs2_glock *gl)
|
|||||||
|
|
||||||
struct buffer_head *gfs2_getbuf(struct gfs2_glock *gl, u64 blkno, int create)
|
struct buffer_head *gfs2_getbuf(struct gfs2_glock *gl, u64 blkno, int create)
|
||||||
{
|
{
|
||||||
struct address_space *mapping = gl->gl_aspace->i_mapping;
|
struct address_space *mapping = gfs2_glock2aspace(gl);
|
||||||
struct gfs2_sbd *sdp = gl->gl_sbd;
|
struct gfs2_sbd *sdp = gl->gl_sbd;
|
||||||
struct page *page;
|
struct page *page;
|
||||||
struct buffer_head *bh;
|
struct buffer_head *bh;
|
||||||
@ -344,8 +308,10 @@ void gfs2_attach_bufdata(struct gfs2_glock *gl, struct buffer_head *bh,
|
|||||||
|
|
||||||
void gfs2_remove_from_journal(struct buffer_head *bh, struct gfs2_trans *tr, int meta)
|
void gfs2_remove_from_journal(struct buffer_head *bh, struct gfs2_trans *tr, int meta)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = GFS2_SB(bh->b_page->mapping->host);
|
struct address_space *mapping = bh->b_page->mapping;
|
||||||
|
struct gfs2_sbd *sdp = gfs2_mapping2sbd(mapping);
|
||||||
struct gfs2_bufdata *bd = bh->b_private;
|
struct gfs2_bufdata *bd = bh->b_private;
|
||||||
|
|
||||||
if (test_clear_buffer_pinned(bh)) {
|
if (test_clear_buffer_pinned(bh)) {
|
||||||
list_del_init(&bd->bd_le.le_list);
|
list_del_init(&bd->bd_le.le_list);
|
||||||
if (meta) {
|
if (meta) {
|
||||||
|
@ -37,8 +37,16 @@ static inline void gfs2_buffer_copy_tail(struct buffer_head *to_bh,
|
|||||||
0, from_head - to_head);
|
0, from_head - to_head);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct inode *gfs2_aspace_get(struct gfs2_sbd *sdp);
|
extern const struct address_space_operations gfs2_meta_aops;
|
||||||
void gfs2_aspace_put(struct inode *aspace);
|
|
||||||
|
static inline struct gfs2_sbd *gfs2_mapping2sbd(struct address_space *mapping)
|
||||||
|
{
|
||||||
|
struct inode *inode = mapping->host;
|
||||||
|
if (mapping->a_ops == &gfs2_meta_aops)
|
||||||
|
return (((struct gfs2_glock *)mapping) - 1)->gl_sbd;
|
||||||
|
else
|
||||||
|
return inode->i_sb->s_fs_info;
|
||||||
|
}
|
||||||
|
|
||||||
void gfs2_meta_sync(struct gfs2_glock *gl);
|
void gfs2_meta_sync(struct gfs2_glock *gl);
|
||||||
|
|
||||||
|
@ -65,7 +65,6 @@ static void gfs2_tune_init(struct gfs2_tune *gt)
|
|||||||
gt->gt_quota_scale_den = 1;
|
gt->gt_quota_scale_den = 1;
|
||||||
gt->gt_new_files_jdata = 0;
|
gt->gt_new_files_jdata = 0;
|
||||||
gt->gt_max_readahead = 1 << 18;
|
gt->gt_max_readahead = 1 << 18;
|
||||||
gt->gt_stall_secs = 600;
|
|
||||||
gt->gt_complain_secs = 10;
|
gt->gt_complain_secs = 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1241,10 +1240,9 @@ fail_sb:
|
|||||||
fail_locking:
|
fail_locking:
|
||||||
init_locking(sdp, &mount_gh, UNDO);
|
init_locking(sdp, &mount_gh, UNDO);
|
||||||
fail_lm:
|
fail_lm:
|
||||||
|
invalidate_inodes(sb);
|
||||||
gfs2_gl_hash_clear(sdp);
|
gfs2_gl_hash_clear(sdp);
|
||||||
gfs2_lm_unmount(sdp);
|
gfs2_lm_unmount(sdp);
|
||||||
while (invalidate_inodes(sb))
|
|
||||||
yield();
|
|
||||||
fail_sys:
|
fail_sys:
|
||||||
gfs2_sys_fs_del(sdp);
|
gfs2_sys_fs_del(sdp);
|
||||||
fail:
|
fail:
|
||||||
|
@ -722,8 +722,7 @@ static int gfs2_write_inode(struct inode *inode, int sync)
|
|||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
/* Check this is a "normal" inode, etc */
|
/* Check this is a "normal" inode, etc */
|
||||||
if (!test_bit(GIF_USER, &ip->i_flags) ||
|
if (current->flags & PF_MEMALLOC)
|
||||||
(current->flags & PF_MEMALLOC))
|
|
||||||
return 0;
|
return 0;
|
||||||
ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
|
ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
|
||||||
if (ret)
|
if (ret)
|
||||||
@ -860,6 +859,7 @@ restart:
|
|||||||
gfs2_clear_rgrpd(sdp);
|
gfs2_clear_rgrpd(sdp);
|
||||||
gfs2_jindex_free(sdp);
|
gfs2_jindex_free(sdp);
|
||||||
/* Take apart glock structures and buffer lists */
|
/* Take apart glock structures and buffer lists */
|
||||||
|
invalidate_inodes(sdp->sd_vfs);
|
||||||
gfs2_gl_hash_clear(sdp);
|
gfs2_gl_hash_clear(sdp);
|
||||||
/* Unmount the locking protocol */
|
/* Unmount the locking protocol */
|
||||||
gfs2_lm_unmount(sdp);
|
gfs2_lm_unmount(sdp);
|
||||||
@ -1194,7 +1194,7 @@ static void gfs2_drop_inode(struct inode *inode)
|
|||||||
{
|
{
|
||||||
struct gfs2_inode *ip = GFS2_I(inode);
|
struct gfs2_inode *ip = GFS2_I(inode);
|
||||||
|
|
||||||
if (test_bit(GIF_USER, &ip->i_flags) && inode->i_nlink) {
|
if (inode->i_nlink) {
|
||||||
struct gfs2_glock *gl = ip->i_iopen_gh.gh_gl;
|
struct gfs2_glock *gl = ip->i_iopen_gh.gh_gl;
|
||||||
if (gl && test_bit(GLF_DEMOTE, &gl->gl_flags))
|
if (gl && test_bit(GLF_DEMOTE, &gl->gl_flags))
|
||||||
clear_nlink(inode);
|
clear_nlink(inode);
|
||||||
@ -1212,18 +1212,12 @@ static void gfs2_clear_inode(struct inode *inode)
|
|||||||
{
|
{
|
||||||
struct gfs2_inode *ip = GFS2_I(inode);
|
struct gfs2_inode *ip = GFS2_I(inode);
|
||||||
|
|
||||||
/* This tells us its a "real" inode and not one which only
|
ip->i_gl->gl_object = NULL;
|
||||||
* serves to contain an address space (see rgrp.c, meta_io.c)
|
gfs2_glock_put(ip->i_gl);
|
||||||
* which therefore doesn't have its own glocks.
|
ip->i_gl = NULL;
|
||||||
*/
|
if (ip->i_iopen_gh.gh_gl) {
|
||||||
if (test_bit(GIF_USER, &ip->i_flags)) {
|
ip->i_iopen_gh.gh_gl->gl_object = NULL;
|
||||||
ip->i_gl->gl_object = NULL;
|
gfs2_glock_dq_uninit(&ip->i_iopen_gh);
|
||||||
gfs2_glock_put(ip->i_gl);
|
|
||||||
ip->i_gl = NULL;
|
|
||||||
if (ip->i_iopen_gh.gh_gl) {
|
|
||||||
ip->i_iopen_gh.gh_gl->gl_object = NULL;
|
|
||||||
gfs2_glock_dq_uninit(&ip->i_iopen_gh);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1358,9 +1352,6 @@ static void gfs2_delete_inode(struct inode *inode)
|
|||||||
struct gfs2_holder gh;
|
struct gfs2_holder gh;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
if (!test_bit(GIF_USER, &ip->i_flags))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
|
error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
|
||||||
if (unlikely(error)) {
|
if (unlikely(error)) {
|
||||||
gfs2_glock_dq_uninit(&ip->i_iopen_gh);
|
gfs2_glock_dq_uninit(&ip->i_iopen_gh);
|
||||||
|
@ -478,7 +478,6 @@ TUNE_ATTR(complain_secs, 0);
|
|||||||
TUNE_ATTR(statfs_slow, 0);
|
TUNE_ATTR(statfs_slow, 0);
|
||||||
TUNE_ATTR(new_files_jdata, 0);
|
TUNE_ATTR(new_files_jdata, 0);
|
||||||
TUNE_ATTR(quota_simul_sync, 1);
|
TUNE_ATTR(quota_simul_sync, 1);
|
||||||
TUNE_ATTR(stall_secs, 1);
|
|
||||||
TUNE_ATTR(statfs_quantum, 1);
|
TUNE_ATTR(statfs_quantum, 1);
|
||||||
TUNE_ATTR_3(quota_scale, quota_scale_show, quota_scale_store);
|
TUNE_ATTR_3(quota_scale, quota_scale_show, quota_scale_store);
|
||||||
|
|
||||||
@ -491,7 +490,6 @@ static struct attribute *tune_attrs[] = {
|
|||||||
&tune_attr_complain_secs.attr,
|
&tune_attr_complain_secs.attr,
|
||||||
&tune_attr_statfs_slow.attr,
|
&tune_attr_statfs_slow.attr,
|
||||||
&tune_attr_quota_simul_sync.attr,
|
&tune_attr_quota_simul_sync.attr,
|
||||||
&tune_attr_stall_secs.attr,
|
|
||||||
&tune_attr_statfs_quantum.attr,
|
&tune_attr_statfs_quantum.attr,
|
||||||
&tune_attr_quota_scale.attr,
|
&tune_attr_quota_scale.attr,
|
||||||
&tune_attr_new_files_jdata.attr,
|
&tune_attr_new_files_jdata.attr,
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
struct kmem_cache *gfs2_glock_cachep __read_mostly;
|
struct kmem_cache *gfs2_glock_cachep __read_mostly;
|
||||||
|
struct kmem_cache *gfs2_glock_aspace_cachep __read_mostly;
|
||||||
struct kmem_cache *gfs2_inode_cachep __read_mostly;
|
struct kmem_cache *gfs2_inode_cachep __read_mostly;
|
||||||
struct kmem_cache *gfs2_bufdata_cachep __read_mostly;
|
struct kmem_cache *gfs2_bufdata_cachep __read_mostly;
|
||||||
struct kmem_cache *gfs2_rgrpd_cachep __read_mostly;
|
struct kmem_cache *gfs2_rgrpd_cachep __read_mostly;
|
||||||
|
@ -145,6 +145,7 @@ gfs2_io_error_bh_i((sdp), (bh), __func__, __FILE__, __LINE__);
|
|||||||
|
|
||||||
|
|
||||||
extern struct kmem_cache *gfs2_glock_cachep;
|
extern struct kmem_cache *gfs2_glock_cachep;
|
||||||
|
extern struct kmem_cache *gfs2_glock_aspace_cachep;
|
||||||
extern struct kmem_cache *gfs2_inode_cachep;
|
extern struct kmem_cache *gfs2_inode_cachep;
|
||||||
extern struct kmem_cache *gfs2_bufdata_cachep;
|
extern struct kmem_cache *gfs2_bufdata_cachep;
|
||||||
extern struct kmem_cache *gfs2_rgrpd_cachep;
|
extern struct kmem_cache *gfs2_rgrpd_cachep;
|
||||||
|
@ -179,33 +179,6 @@ struct gfs2_rgrp {
|
|||||||
__u8 rg_reserved[80]; /* Several fields from gfs1 now reserved */
|
__u8 rg_reserved[80]; /* Several fields from gfs1 now reserved */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* quota linked list: user quotas and group quotas form two separate
|
|
||||||
* singly linked lists. ll_next stores uids or gids of next quotas in the
|
|
||||||
* linked list.
|
|
||||||
|
|
||||||
Given the uid/gid, how to calculate the quota file offsets for the corresponding
|
|
||||||
gfs2_quota structures on disk:
|
|
||||||
|
|
||||||
for user quotas, given uid,
|
|
||||||
offset = uid * sizeof(struct gfs2_quota);
|
|
||||||
|
|
||||||
for group quotas, given gid,
|
|
||||||
offset = (gid * sizeof(struct gfs2_quota)) + sizeof(struct gfs2_quota);
|
|
||||||
|
|
||||||
|
|
||||||
uid:0 gid:0 uid:12 gid:12 uid:17 gid:17 uid:5142 gid:5142
|
|
||||||
+-------+-------+ +-------+-------+ +-------+- - - -+ +- - - -+-------+
|
|
||||||
| valid | valid | :: | valid | valid | :: | valid | inval | :: | inval | valid |
|
|
||||||
+-------+-------+ +-------+-------+ +-------+- - - -+ +- - - -+-------+
|
|
||||||
next:12 next:12 next:17 next:5142 next:NULL next:NULL
|
|
||||||
| | | | |<-- user quota list |
|
|
||||||
\______|___________/ \______|___________/ group quota list -->|
|
|
||||||
| | |
|
|
||||||
\__________________/ \_______________________________________/
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* quota structure
|
* quota structure
|
||||||
*/
|
*/
|
||||||
@ -214,8 +187,7 @@ struct gfs2_quota {
|
|||||||
__be64 qu_limit;
|
__be64 qu_limit;
|
||||||
__be64 qu_warn;
|
__be64 qu_warn;
|
||||||
__be64 qu_value;
|
__be64 qu_value;
|
||||||
__be32 qu_ll_next; /* location of next quota in list */
|
__u8 qu_reserved[64];
|
||||||
__u8 qu_reserved[60];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user