mirror of
https://github.com/ceph/ceph
synced 2025-01-10 05:00:59 +00:00
kclient: separate thread/workqueue to do inode writeback
This commit is contained in:
parent
28f6aaf8f5
commit
cfa62eac0f
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user