Whamcloud - gitweb
LU-13335 ldiskfs: add projid to debug logs
[fs/lustre-release.git] / lustre / llite / file.c
index c87deda..73c256c 100644 (file)
@@ -46,7 +46,6 @@
 #include <linux/ktime.h>
 
 #include <uapi/linux/lustre/lustre_ioctl.h>
-#include <uapi/linux/llcrypt.h>
 #include <lustre_swab.h>
 
 #include "cl_object.h"
@@ -105,7 +104,16 @@ static void ll_prepare_close(struct inode *inode, struct md_op_data *op_data,
        op_data->op_attr.ia_atime = inode->i_atime;
        op_data->op_attr.ia_mtime = inode->i_mtime;
        op_data->op_attr.ia_ctime = inode->i_ctime;
-       op_data->op_attr.ia_size = i_size_read(inode);
+       /* In case of encrypted file without the key, visible size was rounded
+        * up to next LUSTRE_ENCRYPTION_UNIT_SIZE, and clear text size was
+        * stored into lli_lazysize in ll_merge_attr(), so set proper file size
+        * now that we are closing.
+        */
+       if (llcrypt_require_key(inode) == -ENOKEY &&
+           ll_i2info(inode)->lli_attr_valid & OBD_MD_FLLAZYSIZE)
+               op_data->op_attr.ia_size = ll_i2info(inode)->lli_lazysize;
+       else
+               op_data->op_attr.ia_size = i_size_read(inode);
        op_data->op_attr.ia_valid |= (ATTR_MODE | ATTR_ATIME | ATTR_ATIME_SET |
                                      ATTR_MTIME | ATTR_MTIME_SET |
                                      ATTR_CTIME);
@@ -163,7 +171,7 @@ static int ll_close_inode_openhandle(struct inode *inode,
                op_data->op_attr_blocks += ((struct inode *)data)->i_blocks;
                op_data->op_attr.ia_valid |= ATTR_SIZE;
                op_data->op_xvalid |= OP_XVALID_BLOCKS;
-               /* fallthrough */
+               fallthrough;
        case MDS_CLOSE_LAYOUT_SPLIT:
        case MDS_CLOSE_LAYOUT_SWAP: {
                struct split_param *sp = data;
@@ -435,11 +443,15 @@ out:
 
 static inline int ll_dom_readpage(void *data, struct page *page)
 {
+       /* since ll_dom_readpage is a page cache helper, it is safe to assume
+        * mapping and host pointers are set here
+        */
+       struct inode *inode;
        struct niobuf_local *lnb = data;
        void *kaddr;
        int rc = 0;
 
-       struct inode *inode = page2inode(page);
+       inode = page2inode(page);
 
        kaddr = kmap_atomic(page);
        memcpy(kaddr, lnb->lnb_data, lnb->lnb_len);
@@ -582,7 +594,7 @@ void ll_dom_finish_open(struct inode *inode, struct ptlrpc_request *req)
                        put_page(vmpage);
                        break;
                }
-               cl_page_export(env, page, 1);
+               SetPageUptodate(vmpage);
                cl_page_put(env, page);
                unlock_page(vmpage);
                put_page(vmpage);
@@ -755,8 +767,6 @@ static int ll_local_open(struct file *file, struct lookup_intent *it,
        file->private_data = fd;
        ll_readahead_init(inode, &fd->fd_ras);
        fd->fd_omode = it->it_flags & (FMODE_READ | FMODE_WRITE | FMODE_EXEC);
-       /* turn off the kernel's read-ahead */
-       file->f_ra.ra_pages = 0;
 
        RETURN(0);
 }
@@ -816,9 +826,12 @@ int ll_file_open(struct inode *inode, struct file *file)
        file->private_data = NULL; /* prevent ll_local_open assertion */
 
        if (S_ISREG(inode->i_mode)) {
-               rc = llcrypt_file_open(inode, file);
-               if (rc)
+               rc = ll_file_open_encrypt(inode, file);
+               if (rc) {
+                       if (it && it->it_disposition)
+                               ll_release_openhandle(file_dentry(file), it);
                        GOTO(out_nofiledata, rc);
+               }
        }
 
        fd = ll_file_data_get();
@@ -1274,8 +1287,8 @@ static int ll_check_swap_layouts_validity(struct inode *inode1,
        if (!S_ISREG(inode1->i_mode) || !S_ISREG(inode2->i_mode))
                return -EINVAL;
 
-       if (inode_permission(inode1, MAY_WRITE) ||
-           inode_permission(inode2, MAY_WRITE))
+       if (inode_permission(&init_user_ns, inode1, MAY_WRITE) ||
+           inode_permission(&init_user_ns, inode2, MAY_WRITE))
                return -EPERM;
 
        if (inode1->i_sb != inode2->i_sb)
@@ -1467,6 +1480,16 @@ int ll_merge_attr(const struct lu_env *env, struct inode *inode)
        CDEBUG(D_VFSTRACE, DFID" updating i_size %llu\n",
               PFID(&lli->lli_fid), attr->cat_size);
 
+       if (llcrypt_require_key(inode) == -ENOKEY) {
+               /* Without the key, round up encrypted file size to next
+                * LUSTRE_ENCRYPTION_UNIT_SIZE. Clear text size is put in
+                * lli_lazysize for proper file size setting at close time.
+                */
+               lli->lli_attr_valid |= OBD_MD_FLLAZYSIZE;
+               lli->lli_lazysize = attr->cat_size;
+               attr->cat_size = round_up(attr->cat_size,
+                                         LUSTRE_ENCRYPTION_UNIT_SIZE);
+       }
        i_size_write(inode, attr->cat_size);
        inode->i_blocks = attr->cat_blocks;
 
@@ -1554,6 +1577,12 @@ void ll_io_init(struct cl_io *io, struct file *file, enum cl_io_type iot,
 #endif
        }
 
+#ifdef IOCB_NOWAIT
+       io->ci_iocb_nowait = !!(args &&
+                               (args->u.normal.via_iocb->ki_flags &
+                                IOCB_NOWAIT));
+#endif
+
        io->ci_obj = ll_i2info(inode)->lli_clob;
        io->ci_lockreq = CILR_MAYBE;
        if (ll_file_nolock(file)) {
@@ -1640,6 +1669,8 @@ ll_file_io_generic(const struct lu_env *env, struct vvp_io_args *args,
 
        io = vvp_env_thread_io(env);
        if (file->f_flags & O_DIRECT) {
+               if (file->f_flags & O_APPEND)
+                       dio_lock = 1;
                if (!is_sync_kiocb(args->u.normal.via_iocb))
                        is_aio = true;
 
@@ -1654,7 +1685,7 @@ ll_file_io_generic(const struct lu_env *env, struct vvp_io_args *args,
                        is_parallel_dio = false;
 
                ci_aio = cl_aio_alloc(args->u.normal.via_iocb,
-                                     ll_i2info(inode)->lli_clob);
+                                     ll_i2info(inode)->lli_clob, NULL);
                if (!ci_aio)
                        GOTO(out, rc = -ENOMEM);
        }
@@ -1920,8 +1951,15 @@ static ssize_t ll_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
        ktime_t kstart = ktime_get();
        bool cached;
 
+       ENTRY;
+
+       CDEBUG(D_VFSTRACE|D_IOTRACE, "file %s:"DFID", ppos: %lld, count: %zu\n",
+              file_dentry(file)->d_name.name,
+              PFID(ll_inode2fid(file_inode(file))), iocb->ki_pos,
+              iov_iter_count(to));
+
        if (!iov_iter_count(to))
-               return 0;
+               RETURN(0);
 
        /**
         * Currently when PCC read failed, we do not fall back to the
@@ -1946,7 +1984,7 @@ static ssize_t ll_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
 
        env = cl_env_get(&refcheck);
        if (IS_ERR(env))
-               return PTR_ERR(env);
+               RETURN(PTR_ERR(env));
 
        args = ll_env_args(env);
        args->u.normal.via_iter = to;
@@ -1969,7 +2007,13 @@ out:
                                   ktime_us_delta(ktime_get(), kstart));
        }
 
-       return result;
+       CDEBUG(D_IOTRACE,
+              "COMPLETED: file %s:"DFID", ppos: %lld, count: %zu\n",
+              file_dentry(file)->d_name.name,
+              PFID(ll_inode2fid(file_inode(file))), iocb->ki_pos,
+              iov_iter_count(to));
+
+       RETURN(result);
 }
 
 /**
@@ -2045,6 +2089,11 @@ static ssize_t ll_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
 
        ENTRY;
 
+       CDEBUG(D_VFSTRACE|D_IOTRACE, "file %s:"DFID", ppos: %lld, count: %zu\n",
+              file_dentry(file)->d_name.name,
+              PFID(ll_inode2fid(file_inode(file))), iocb->ki_pos,
+              iov_iter_count(from));
+
        if (!iov_iter_count(from))
                GOTO(out, rc_normal = 0);
 
@@ -2079,7 +2128,7 @@ static ssize_t ll_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
 
        env = cl_env_get(&refcheck);
        if (IS_ERR(env))
-               return PTR_ERR(env);
+               RETURN(PTR_ERR(env));
 
        args = ll_env_args(env);
        args->u.normal.via_iter = from;
@@ -2107,6 +2156,12 @@ out:
                                   ktime_us_delta(ktime_get(), kstart));
        }
 
+       CDEBUG(D_IOTRACE,
+              "COMPLETED: file %s:"DFID", ppos: %lld, count: %zu\n",
+              file_dentry(file)->d_name.name,
+              PFID(ll_inode2fid(file_inode(file))), iocb->ki_pos,
+              iov_iter_count(from));
+
        RETURN(rc_normal);
 }
 
@@ -2719,7 +2774,7 @@ static int ll_do_fiemap(struct inode *inode, struct fiemap *fiemap,
                        GOTO(out, rc);
        }
 
-       fmkey.lfik_oa.o_valid = OBD_MD_FLID | OBD_MD_FLGROUP;
+       fmkey.lfik_oa.o_valid = OBD_MD_FLID | OBD_MD_FLGROUP | OBD_MD_FLPROJID;
        obdo_from_inode(&fmkey.lfik_oa, inode, OBD_MD_FLSIZE);
        obdo_set_parent_fid(&fmkey.lfik_oa, &ll_i2info(inode)->lli_fid);
 
@@ -2863,8 +2918,9 @@ int ll_hsm_release(struct inode *inode)
        struct lu_env *env;
        struct obd_client_handle *och = NULL;
        __u64 data_version = 0;
-       int rc;
        __u16 refcheck;
+       int rc;
+
        ENTRY;
 
        CDEBUG(D_INODE, "%s: Releasing file "DFID".\n",
@@ -2876,7 +2932,8 @@ int ll_hsm_release(struct inode *inode)
                GOTO(out, rc = PTR_ERR(och));
 
        /* Grab latest data_version and [am]time values */
-       rc = ll_data_version(inode, &data_version, LL_DV_WR_FLUSH);
+       rc = ll_data_version(inode, &data_version,
+                            LL_DV_WR_FLUSH | LL_DV_SZ_UPDATE);
        if (rc != 0)
                GOTO(out, rc);
 
@@ -3314,7 +3371,7 @@ static int ll_ladvise_sanity(struct inode *inode,
                               ladvise_names[advice], rc);
                        GOTO(out, rc);
                }
-               /* fallthrough */
+               fallthrough;
        case LU_LADVISE_WILLREAD:
        case LU_LADVISE_DONTNEED:
        default:
@@ -3458,12 +3515,14 @@ int ll_ioctl_check_project(struct inode *inode, __u32 xflags,
 
 static int ll_set_project(struct inode *inode, __u32 xflags, __u32 projid)
 {
-       struct md_op_data *op_data;
        struct ptlrpc_request *req = NULL;
+       struct md_op_data *op_data;
        struct cl_object *obj;
        unsigned int inode_flags;
        int rc = 0;
 
+       CDEBUG(D_QUOTA, DFID" xflags=%x projid=%u\n",
+              PFID(ll_inode2fid(inode)), xflags, projid);
        rc = ll_ioctl_check_project(inode, xflags, projid);
        if (rc)
                RETURN(rc);
@@ -3477,7 +3536,10 @@ static int ll_set_project(struct inode *inode, __u32 xflags, __u32 projid)
        op_data->op_attr_flags = ll_inode_to_ext_flags(inode_flags);
        if (xflags & FS_XFLAG_PROJINHERIT)
                op_data->op_attr_flags |= LUSTRE_PROJINHERIT_FL;
+
+       /* pass projid to md_op_data */
        op_data->op_projid = projid;
+
        op_data->op_xvalid |= OP_XVALID_PROJID | OP_XVALID_FLAGS;
        rc = md_setattr(ll_i2sbi(inode)->ll_md_exp, op_data, NULL, 0, &req);
        ptlrpc_req_finished(req);
@@ -4005,9 +4067,7 @@ out:
                 RETURN(0);
         }
        case OBD_IOC_GETNAME_OLD:
-               /* fall through */
        case OBD_IOC_GETDTNAME:
-               /* fall through */
        case OBD_IOC_GETMDNAME:
                RETURN(ll_get_obd_name(inode, cmd, arg));
        case LL_IOC_HSM_STATE_GET: {
@@ -4301,7 +4361,7 @@ out_ladvise:
                if (!S_ISREG(inode->i_mode))
                        GOTO(out_detach_free, rc = -EINVAL);
 
-               if (!inode_owner_or_capable(inode))
+               if (!inode_owner_or_capable(&init_user_ns, inode))
                        GOTO(out_detach_free, rc = -EPERM);
 
                rc = pcc_ioctl_detach(inode, detach->pccd_opt);
@@ -4420,6 +4480,12 @@ loff_t ll_lseek(struct file *file, loff_t offset, int whence)
 
        cl_env_put(env, &refcheck);
 
+       /* Without the key, SEEK_HOLE return value has to be
+        * rounded up to next LUSTRE_ENCRYPTION_UNIT_SIZE.
+        */
+       if (llcrypt_require_key(inode) == -ENOKEY && whence == SEEK_HOLE)
+               retval = round_up(retval, LUSTRE_ENCRYPTION_UNIT_SIZE);
+
        RETURN(retval);
 }
 
@@ -4790,7 +4856,7 @@ out_req:
 }
 
 int ll_migrate(struct inode *parent, struct file *file, struct lmv_user_md *lum,
-              const char *name)
+              const char *name, __u32 flags)
 {
        struct dentry *dchild = NULL;
        struct inode *child_inode = NULL;
@@ -4852,26 +4918,8 @@ int ll_migrate(struct inode *parent, struct file *file, struct lmv_user_md *lum,
        if (is_root_inode(child_inode))
                GOTO(out_iput, rc = -EINVAL);
 
-       if (IS_ENCRYPTED(child_inode)) {
-               rc = llcrypt_get_encryption_info(child_inode);
-               if (rc)
-                       GOTO(out_iput, rc);
-               if (!llcrypt_has_encryption_key(child_inode)) {
-                       CDEBUG(D_SEC, "no enc key for "DFID"\n",
-                              PFID(ll_inode2fid(child_inode)));
-                       GOTO(out_iput, rc = -ENOKEY);
-               }
-               if (unlikely(!llcrypt_policy_has_filename_enc(child_inode))) {
-                       CDEBUG(D_SEC,
-                              "cannot migrate old format encrypted "DFID", please move to new enc dir first\n",
-                              PFID(ll_inode2fid(child_inode)));
-                       GOTO(out_iput, rc = -EUCLEAN);
-               }
-       }
-
        op_data = ll_prep_md_op_data(NULL, parent, NULL, name, namelen,
-                                    child_inode->i_mode, LUSTRE_OPC_MIGR,
-                                    NULL);
+                                    child_inode->i_mode, LUSTRE_OPC_ANY, NULL);
        if (IS_ERR(op_data))
                GOTO(out_iput, rc = PTR_ERR(op_data));
 
@@ -4888,6 +4936,11 @@ int ll_migrate(struct inode *parent, struct file *file, struct lmv_user_md *lum,
        op_data->op_data = lum;
        op_data->op_data_size = lumlen;
 
+       /* migrate dirent only for subdirs if MDS_MIGRATE_NSONLY set */
+       if (S_ISDIR(child_inode->i_mode) && (flags & MDS_MIGRATE_NSONLY) &&
+           lmv_dir_layout_changing(ll_i2info(parent)->lli_lsm_md))
+               op_data->op_bias |= MDS_MIGRATE_NSONLY;
+
 again:
        if (S_ISREG(child_inode->i_mode)) {
                och = ll_lease_open(child_inode, NULL, FMODE_WRITE, 0);
@@ -4971,7 +5024,7 @@ ll_file_noflock(struct file *file, int cmd, struct file_lock *file_lock)
         */
        if (!(fd->fd_flags & LL_FILE_FLOCK_WARNING)) {
                fd->fd_flags |= LL_FILE_FLOCK_WARNING;
-               CDEBUG_LIMIT(D_TTY | D_CONSOLE,
+               CDEBUG_LIMIT(D_CONSOLE,
                             "flock disabled, mount with '-o [local]flock' to enable\r\n");
        }
        RETURN(-ENOSYS);
@@ -5139,12 +5192,14 @@ static int ll_merge_md_attr(struct inode *inode)
        struct cl_attr attr = { 0 };
        int rc;
 
-       LASSERT(lli->lli_lsm_md != NULL);
-
-       if (!lmv_dir_striped(lli->lli_lsm_md))
+       if (!lli->lli_lsm_md)
                RETURN(0);
 
        down_read(&lli->lli_lsm_sem);
+       if (!lmv_dir_striped(lli->lli_lsm_md)) {
+               up_read(&lli->lli_lsm_sem);
+               RETURN(0);
+       }
        rc = md_merge_attr(ll_i2mdexp(inode), ll_i2info(inode)->lli_lsm_md,
                           &attr, ll_md_blocking_ast);
        up_read(&lli->lli_lsm_sem);
@@ -5294,7 +5349,7 @@ fill_attr:
        stat->size = i_size_read(inode);
        stat->blocks = inode->i_blocks;
 
-#ifdef HAVE_INODEOPS_ENHANCED_GETATTR
+#if defined(HAVE_USER_NAMESPACE_ARG) || defined(HAVE_INODEOPS_ENHANCED_GETATTR)
        if (flags & AT_STATX_DONT_SYNC) {
                if (stat->size == 0 &&
                    lli->lli_attr_valid & OBD_MD_FLLAZYSIZE)
@@ -5320,9 +5375,9 @@ fill_attr:
        return 0;
 }
 
-#ifdef HAVE_INODEOPS_ENHANCED_GETATTR
-int ll_getattr(const struct path *path, struct kstat *stat,
-              u32 request_mask, unsigned int flags)
+#if defined(HAVE_USER_NAMESPACE_ARG) || defined(HAVE_INODEOPS_ENHANCED_GETATTR)
+int ll_getattr(struct user_namespace *mnt_userns, const struct path *path,
+              struct kstat *stat, u32 request_mask, unsigned int flags)
 {
        return ll_getattr_dentry(path->dentry, stat, request_mask, flags,
                                 false);
@@ -5338,11 +5393,11 @@ int ll_getattr(struct vfsmount *mnt, struct dentry *de, struct kstat *stat)
 int cl_falloc(struct file *file, struct inode *inode, int mode, loff_t offset,
              loff_t len)
 {
+       loff_t size = i_size_read(inode);
        struct lu_env *env;
        struct cl_io *io;
        __u16 refcheck;
        int rc;
-       loff_t size = i_size_read(inode);
 
        ENTRY;
 
@@ -5360,6 +5415,16 @@ int cl_falloc(struct file *file, struct inode *inode, int mode, loff_t offset,
        io->u.ci_setattr.sa_falloc_offset = offset;
        io->u.ci_setattr.sa_falloc_end = offset + len;
        io->u.ci_setattr.sa_subtype = CL_SETATTR_FALLOCATE;
+
+       CDEBUG(D_INODE, "UID %u GID %u PRJID %u\n",
+              from_kuid(&init_user_ns, inode->i_uid),
+              from_kgid(&init_user_ns, inode->i_gid),
+              ll_i2info(inode)->lli_projid);
+
+       io->u.ci_setattr.sa_falloc_uid = from_kuid(&init_user_ns, inode->i_uid);
+       io->u.ci_setattr.sa_falloc_gid = from_kgid(&init_user_ns, inode->i_gid);
+       io->u.ci_setattr.sa_falloc_projid = ll_i2info(inode)->lli_projid;
+
        if (io->u.ci_setattr.sa_falloc_end > size) {
                loff_t newsize = io->u.ci_setattr.sa_falloc_end;
 
@@ -5477,7 +5542,8 @@ out:
        return rc;
 }
 
-int ll_inode_permission(struct inode *inode, int mask)
+int ll_inode_permission(struct user_namespace *mnt_userns, struct inode *inode,
+                       int mask)
 {
        int rc = 0;
        struct ll_sb_info *sbi;
@@ -5533,7 +5599,7 @@ int ll_inode_permission(struct inode *inode, int mask)
                old_cred = override_creds(cred);
        }
 
-       rc = generic_permission(inode, mask);
+       rc = generic_permission(mnt_userns, inode, mask);
        /* restore current process's credentials and FS capability */
        if (squash_id) {
                revert_creds(old_cred);