kclient: separate thread/workqueue to do inode writeback

This commit is contained in:
Sage Weil 2008-04-10 13:43:42 -07:00
parent 28f6aaf8f5
commit cfa62eac0f
4 changed files with 34 additions and 8 deletions

View File

@ -177,7 +177,7 @@ struct ceph_client *ceph_create_client(struct ceph_mount_args *args, struct supe
{
struct ceph_client *cl;
struct ceph_entity_addr *myaddr = 0;
int err;
int err = -ENOMEM;
cl = kzalloc(sizeof(*cl), GFP_KERNEL);
if (cl == NULL)
@ -187,6 +187,10 @@ struct ceph_client *ceph_create_client(struct ceph_mount_args *args, struct supe
spin_lock_init(&cl->sb_lock);
get_client_counter();
cl->wb_wq = create_workqueue("ceph-writeback");
if (cl->wb_wq == 0)
goto fail;
/* messenger */
if (args->flags & CEPH_MOUNT_MYIP)
myaddr = &args->my_addr;
@ -231,6 +235,7 @@ void ceph_destroy_client(struct ceph_client *cl)
ceph_messenger_destroy(cl->msgr);
put_client_counter();
destroy_workqueue(cl->wb_wq);
kfree(cl);
dout(10, "destroy_client %p done\n", cl);
}

View File

@ -1024,20 +1024,27 @@ out:
wake_up(&ci->i_cap_wq);
if (writeback_now) {
/*
* _queue_ inode for writeback, but don't actually
* call writepages from this context!!
* queue inode for writeback; we can't actually call
* write_inode_now, writepages, etc. from this
* context.
*/
dout(10, "queueing %p for writeback\n", inode);
spin_lock(&inode_lock);
list_move(&inode->i_list, &inode->i_sb->s_more_io);
spin_unlock(&inode_lock);
wakeup_pdflush(0); /* this is overkill? */
ceph_queue_writeback(ceph_client(inode->i_sb), ci);
}
if (invalidate)
invalidate_mapping_pages(&inode->i_data, 0, -1);
return reply;
}
void ceph_inode_writeback(struct work_struct *work)
{
struct ceph_inode_info *ci = container_of(work, struct ceph_inode_info,
i_wb_work);
dout(10, "writeback %p\n", &ci->vfs_inode);
write_inode_now(&ci->vfs_inode, 0);
}
void apply_truncate(struct inode *inode, loff_t size)
{
struct ceph_inode_info *ci = ceph_inode(inode);

View File

@ -152,6 +152,8 @@ static struct inode *ceph_alloc_inode(struct super_block *sb)
ci->i_hashval = 0;
INIT_WORK(&ci->i_wb_work, ceph_inode_writeback);
return &ci->vfs_inode;
}

View File

@ -91,13 +91,15 @@ struct ceph_client {
struct ceph_mds_client mdsc;
struct ceph_osd_client osdc;
/* writeback */
struct workqueue_struct *wb_wq;
/* lets ignore all this until later */
spinlock_t sb_lock;
int num_sb; /* ref count (for each sb_info that points to me) */
struct list_head sb_list;
};
/*
* CEPH per-mount superblock info
*/
@ -167,6 +169,8 @@ struct ceph_inode_info {
unsigned long i_hashval;
struct work_struct i_wb_work; /* writeback work */
struct inode vfs_inode; /* at end */
};
@ -189,6 +193,13 @@ static inline struct ceph_dentry_info *ceph_dentry(struct dentry *dentry)
extern void ceph_revoke_inode_lease(struct ceph_inode_info *ci, int mask);
extern void ceph_revoke_dentry_lease(struct dentry *dentry);
static inline void ceph_queue_writeback(struct ceph_client *cl,
struct ceph_inode_info *ci)
{
queue_work(cl->wb_wq, &ci->i_wb_work);
}
/*
* ino_t is <64 bits on many architectures... blech
*/
@ -382,6 +393,7 @@ extern void ceph_check_caps(struct ceph_inode_info *ci);
extern void ceph_get_mode(struct ceph_inode_info *ci, int mode);
extern void ceph_put_mode(struct ceph_inode_info *ci, int mode);
extern void ceph_inode_set_size(struct inode *inode, loff_t size);
extern void ceph_inode_writeback(struct work_struct *work);
extern int ceph_setattr(struct dentry *dentry, struct iattr *attr);
extern int ceph_inode_getattr(struct vfsmount *mnt, struct dentry *dentry,