]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - fs/ceph/file.c
Merge branch 'for-5.4/wacom' into for-linus
[linux.git] / fs / ceph / file.c
index 183c37c0a8fcdfe4e2d84b096c7e398b950d6027..685a03cc4b77d1cd22ad9d06e87b04f21b9691a6 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/namei.h>
 #include <linux/writeback.h>
 #include <linux/falloc.h>
+#include <linux/iversion.h>
 
 #include "super.h"
 #include "mds_client.h"
@@ -437,7 +438,7 @@ int ceph_atomic_open(struct inode *dir, struct dentry *dentry,
        struct ceph_mds_client *mdsc = fsc->mdsc;
        struct ceph_mds_request *req;
        struct dentry *dn;
-       struct ceph_acls_info acls = {};
+       struct ceph_acl_sec_ctx as_ctx = {};
        int mask;
        int err;
 
@@ -451,25 +452,28 @@ int ceph_atomic_open(struct inode *dir, struct dentry *dentry,
        if (flags & O_CREAT) {
                if (ceph_quota_is_max_files_exceeded(dir))
                        return -EDQUOT;
-               err = ceph_pre_init_acls(dir, &mode, &acls);
+               err = ceph_pre_init_acls(dir, &mode, &as_ctx);
                if (err < 0)
                        return err;
+               err = ceph_security_init_secctx(dentry, mode, &as_ctx);
+               if (err < 0)
+                       goto out_ctx;
        }
 
        /* do the open */
        req = prepare_open_request(dir->i_sb, flags, mode);
        if (IS_ERR(req)) {
                err = PTR_ERR(req);
-               goto out_acl;
+               goto out_ctx;
        }
        req->r_dentry = dget(dentry);
        req->r_num_caps = 2;
        if (flags & O_CREAT) {
                req->r_dentry_drop = CEPH_CAP_FILE_SHARED | CEPH_CAP_AUTH_EXCL;
                req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
-               if (acls.pagelist) {
-                       req->r_pagelist = acls.pagelist;
-                       acls.pagelist = NULL;
+               if (as_ctx.pagelist) {
+                       req->r_pagelist = as_ctx.pagelist;
+                       as_ctx.pagelist = NULL;
                }
        }
 
@@ -507,7 +511,7 @@ int ceph_atomic_open(struct inode *dir, struct dentry *dentry,
        } else {
                dout("atomic_open finish_open on dn %p\n", dn);
                if (req->r_op == CEPH_MDS_OP_CREATE && req->r_reply_info.has_create_ino) {
-                       ceph_init_inode_acls(d_inode(dentry), &acls);
+                       ceph_init_inode_acls(d_inode(dentry), &as_ctx);
                        file->f_mode |= FMODE_CREATED;
                }
                err = finish_open(file, dentry, ceph_open);
@@ -516,8 +520,8 @@ int ceph_atomic_open(struct inode *dir, struct dentry *dentry,
        if (!req->r_err && req->r_target_inode)
                ceph_put_fmode(ceph_inode(req->r_target_inode), req->r_fmode);
        ceph_mdsc_put_request(req);
-out_acl:
-       ceph_release_acls_info(&acls);
+out_ctx:
+       ceph_release_acl_sec_ctx(&as_ctx);
        dout("atomic_open result=%d\n", err);
        return err;
 }
@@ -1007,7 +1011,7 @@ ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter,
                         * may block.
                         */
                        truncate_inode_pages_range(inode->i_mapping, pos,
-                                       (pos+len) | (PAGE_SIZE - 1));
+                                                  PAGE_ALIGN(pos + len) - 1);
 
                        req->r_mtime = mtime;
                }
@@ -1022,7 +1026,7 @@ ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter,
                        req->r_callback = ceph_aio_complete_req;
                        req->r_inode = inode;
                        req->r_priv = aio_req;
-                       list_add_tail(&req->r_unsafe_item, &aio_req->osd_reqs);
+                       list_add_tail(&req->r_private_item, &aio_req->osd_reqs);
 
                        pos += len;
                        continue;
@@ -1082,8 +1086,8 @@ ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter,
                while (!list_empty(&osd_reqs)) {
                        req = list_first_entry(&osd_reqs,
                                               struct ceph_osd_request,
-                                              r_unsafe_item);
-                       list_del_init(&req->r_unsafe_item);
+                                              r_private_item);
+                       list_del_init(&req->r_private_item);
                        if (ret >= 0)
                                ret = ceph_osdc_start_request(req->r_osdc,
                                                              req, false);
@@ -1432,6 +1436,8 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from)
        if (err)
                goto out;
 
+       inode_inc_iversion_raw(inode);
+
        if (ci->i_inline_version != CEPH_INLINE_NONE) {
                err = ceph_uninline_data(file, NULL);
                if (err < 0)
@@ -1889,9 +1895,9 @@ static int is_file_size_ok(struct inode *src_inode, struct inode *dst_inode,
        return 0;
 }
 
-static ssize_t ceph_copy_file_range(struct file *src_file, loff_t src_off,
-                                   struct file *dst_file, loff_t dst_off,
-                                   size_t len, unsigned int flags)
+static ssize_t __ceph_copy_file_range(struct file *src_file, loff_t src_off,
+                                     struct file *dst_file, loff_t dst_off,
+                                     size_t len, unsigned int flags)
 {
        struct inode *src_inode = file_inode(src_file);
        struct inode *dst_inode = file_inode(dst_file);
@@ -1909,6 +1915,8 @@ static ssize_t ceph_copy_file_range(struct file *src_file, loff_t src_off,
 
        if (src_inode == dst_inode)
                return -EINVAL;
+       if (src_inode->i_sb != dst_inode->i_sb)
+               return -EXDEV;
        if (ceph_snap(dst_inode) != CEPH_NOSNAP)
                return -EROFS;
 
@@ -2061,6 +2069,8 @@ static ssize_t ceph_copy_file_range(struct file *src_file, loff_t src_off,
                do_final_copy = true;
 
        file_update_time(dst_file);
+       inode_inc_iversion_raw(dst_inode);
+
        if (endoff > size) {
                int caps_flags = 0;
 
@@ -2100,6 +2110,21 @@ static ssize_t ceph_copy_file_range(struct file *src_file, loff_t src_off,
        return ret;
 }
 
+static ssize_t ceph_copy_file_range(struct file *src_file, loff_t src_off,
+                                   struct file *dst_file, loff_t dst_off,
+                                   size_t len, unsigned int flags)
+{
+       ssize_t ret;
+
+       ret = __ceph_copy_file_range(src_file, src_off, dst_file, dst_off,
+                                    len, flags);
+
+       if (ret == -EOPNOTSUPP || ret == -EXDEV)
+               ret = generic_copy_file_range(src_file, src_off, dst_file,
+                                             dst_off, len, flags);
+       return ret;
+}
+
 const struct file_operations ceph_file_fops = {
        .open = ceph_open,
        .release = ceph_release,