diff options
Diffstat (limited to 'fs/ceph/inode.c')
-rw-r--r-- | fs/ceph/inode.c | 79 |
1 files changed, 22 insertions, 57 deletions
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index adc8fc3c5d85..156f849f5385 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -1816,60 +1816,17 @@ void ceph_async_iput(struct inode *inode) } } -/* - * Write back inode data in a worker thread. (This can't be done - * in the message handler context.) - */ -void ceph_queue_writeback(struct inode *inode) -{ - struct ceph_inode_info *ci = ceph_inode(inode); - set_bit(CEPH_I_WORK_WRITEBACK, &ci->i_work_mask); - - ihold(inode); - if (queue_work(ceph_inode_to_client(inode)->inode_wq, - &ci->i_work)) { - dout("ceph_queue_writeback %p\n", inode); - } else { - dout("ceph_queue_writeback %p already queued, mask=%lx\n", - inode, ci->i_work_mask); - iput(inode); - } -} - -/* - * queue an async invalidation - */ -void ceph_queue_invalidate(struct inode *inode) -{ - struct ceph_inode_info *ci = ceph_inode(inode); - set_bit(CEPH_I_WORK_INVALIDATE_PAGES, &ci->i_work_mask); - - ihold(inode); - if (queue_work(ceph_inode_to_client(inode)->inode_wq, - &ceph_inode(inode)->i_work)) { - dout("ceph_queue_invalidate %p\n", inode); - } else { - dout("ceph_queue_invalidate %p already queued, mask=%lx\n", - inode, ci->i_work_mask); - iput(inode); - } -} - -/* - * Queue an async vmtruncate. If we fail to queue work, we will handle - * the truncation the next time we call __ceph_do_pending_vmtruncate. - */ -void ceph_queue_vmtruncate(struct inode *inode) +void ceph_queue_inode_work(struct inode *inode, int work_bit) { + struct ceph_fs_client *fsc = ceph_inode_to_client(inode); struct ceph_inode_info *ci = ceph_inode(inode); - set_bit(CEPH_I_WORK_VMTRUNCATE, &ci->i_work_mask); + set_bit(work_bit, &ci->i_work_mask); ihold(inode); - if (queue_work(ceph_inode_to_client(inode)->inode_wq, - &ci->i_work)) { - dout("ceph_queue_vmtruncate %p\n", inode); + if (queue_work(fsc->inode_wq, &ci->i_work)) { + dout("queue_inode_work %p, mask=%lx\n", inode, ci->i_work_mask); } else { - dout("ceph_queue_vmtruncate %p already queued, mask=%lx\n", + dout("queue_inode_work %p already queued, mask=%lx\n", inode, ci->i_work_mask); iput(inode); } @@ -2008,6 +1965,12 @@ static void ceph_inode_work(struct work_struct *work) if (test_and_clear_bit(CEPH_I_WORK_VMTRUNCATE, &ci->i_work_mask)) __ceph_do_pending_vmtruncate(inode); + if (test_and_clear_bit(CEPH_I_WORK_CHECK_CAPS, &ci->i_work_mask)) + ceph_check_caps(ci, 0, NULL); + + if (test_and_clear_bit(CEPH_I_WORK_FLUSH_SNAPS, &ci->i_work_mask)) + ceph_flush_snaps(ci, NULL); + iput(inode); } @@ -2238,7 +2201,8 @@ int __ceph_setattr(struct inode *inode, struct iattr *attr) /* * setattr */ -int ceph_setattr(struct dentry *dentry, struct iattr *attr) +int ceph_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, + struct iattr *attr) { struct inode *inode = d_inode(dentry); struct ceph_fs_client *fsc = ceph_inode_to_client(inode); @@ -2247,7 +2211,7 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr) if (ceph_snap(inode) != CEPH_NOSNAP) return -EROFS; - err = setattr_prepare(dentry, attr); + err = setattr_prepare(&init_user_ns, dentry, attr); if (err != 0) return err; @@ -2262,7 +2226,7 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr) err = __ceph_setattr(inode, attr); if (err >= 0 && (attr->ia_valid & ATTR_MODE)) - err = posix_acl_chmod(inode, attr->ia_mode); + err = posix_acl_chmod(&init_user_ns, inode, attr->ia_mode); return err; } @@ -2321,7 +2285,8 @@ int __ceph_do_getattr(struct inode *inode, struct page *locked_page, * Check inode permissions. We verify we have a valid value for * the AUTH cap, then call the generic handler. */ -int ceph_permission(struct inode *inode, int mask) +int ceph_permission(struct user_namespace *mnt_userns, struct inode *inode, + int mask) { int err; @@ -2331,7 +2296,7 @@ int ceph_permission(struct inode *inode, int mask) err = ceph_do_getattr(inode, CEPH_CAP_AUTH_SHARED, false); if (!err) - err = generic_permission(inode, mask); + err = generic_permission(&init_user_ns, inode, mask); return err; } @@ -2368,8 +2333,8 @@ static int statx_to_caps(u32 want, umode_t mode) * Get all the attributes. If we have sufficient caps for the requested attrs, * then we can avoid talking to the MDS at all. */ -int ceph_getattr(const struct path *path, struct kstat *stat, - u32 request_mask, unsigned int flags) +int ceph_getattr(struct user_namespace *mnt_userns, const struct path *path, + struct kstat *stat, u32 request_mask, unsigned int flags) { struct inode *inode = d_inode(path->dentry); struct ceph_inode_info *ci = ceph_inode(inode); @@ -2385,7 +2350,7 @@ int ceph_getattr(const struct path *path, struct kstat *stat, return err; } - generic_fillattr(inode, stat); + generic_fillattr(&init_user_ns, inode, stat); stat->ino = ceph_present_inode(inode); /* |