Whamcloud - gitweb
LU-14877 llite: Remove inode locking in ll_fsync
[fs/lustre-release.git] / lustre / llite / file.c
index a96286f..38d23fc 100644 (file)
@@ -636,6 +636,8 @@ retry:
        op_data->op_data = lmm;
        op_data->op_data_size = lmmsize;
 
+       OBD_FAIL_TIMEOUT(OBD_FAIL_LLITE_OPEN_DELAY, cfs_fail_val);
+
        rc = md_intent_lock(sbi->ll_md_exp, op_data, itp, &req,
                            &ll_md_blocking_ast, 0);
        kfree(name);
@@ -671,8 +673,11 @@ retry:
                 * of kernel will deal with that later.
                 */
                ll_set_lock_data(sbi->ll_md_exp, de->d_inode, itp, &bits);
-               if (bits & MDS_INODELOCK_LOOKUP)
+               if (bits & MDS_INODELOCK_LOOKUP) {
                        d_lustre_revalidate(de);
+                       ll_update_dir_depth(parent->d_inode, de->d_inode);
+               }
+
                /* if DoM bit returned along with LAYOUT bit then there
                 * can be read-on-open data returned.
                 */
@@ -684,14 +689,20 @@ out:
        ptlrpc_req_finished(req);
        ll_intent_drop_lock(itp);
 
-       /* We did open by fid, but by the time we got to the server,
-        * the object disappeared. If this is a create, we cannot really
-        * tell the userspace that the file it was trying to create
-        * does not exist. Instead let's return -ESTALE, and the VFS will
-        * retry the create with LOOKUP_REVAL that we are going to catch
-        * in ll_revalidate_dentry() and use lookup then.
+       /* We did open by fid, but by the time we got to the server, the object
+        * disappeared.  This is possible if the object was unlinked, but it's
+        * also possible if the object was unlinked by a rename.  In the case
+        * of an object renamed over our existing one, we can't fail this open.
+        * O_CREAT also goes through this path if we had an existing dentry,
+        * and it's obviously wrong to return ENOENT for O_CREAT.
+        *
+        * Instead let's return -ESTALE, and the VFS will retry the open with
+        * LOOKUP_REVAL, which we catch in ll_revalidate_dentry and fail to
+        * revalidate, causing a lookup.  This causes extra lookups in the case
+        * where we had a dentry in cache but the file is being unlinked and we
+        * lose the race with unlink, but this should be very rare.
         */
-       if (rc == -ENOENT && itp->it_op & IT_CREAT)
+       if (rc == -ENOENT)
                rc = -ESTALE;
 
        RETURN(rc);
@@ -1635,7 +1646,8 @@ ll_file_io_generic(const struct lu_env *env, struct vvp_io_args *args,
                if (!ll_sbi_has_parallel_dio(sbi))
                        is_parallel_dio = false;
 
-               ci_aio = cl_aio_alloc(args->u.normal.via_iocb);
+               ci_aio = cl_aio_alloc(args->u.normal.via_iocb,
+                                     ll_i2info(inode)->lli_clob);
                if (!ci_aio)
                        GOTO(out, rc = -ENOMEM);
        }
@@ -1790,7 +1802,7 @@ out:
                cl_sync_io_note(env, &io->ci_aio->cda_sync,
                                rc == -EIOCBQUEUED ? 0 : rc);
                if (!is_aio) {
-                       cl_aio_free(io->ci_aio);
+                       cl_aio_free(env, io->ci_aio);
                        io->ci_aio = NULL;
                }
        }
@@ -3413,8 +3425,17 @@ int ll_ioctl_check_project(struct inode *inode, __u32 xflags,
         * namespace. Enforce that restriction only if we are trying to change
         * the quota ID state. Everything else is allowed in user namespaces.
         */
-       if (current_user_ns() == &init_user_ns)
+       if (current_user_ns() == &init_user_ns) {
+               /*
+                * Caller is allowed to change the project ID. if it is being
+                * changed, make sure that the new value is valid.
+                */
+               if (ll_i2info(inode)->lli_projid != projid &&
+                    !projid_valid(make_kprojid(&init_user_ns, projid)))
+                       return -EINVAL;
+
                return 0;
+       }
 
        if (ll_i2info(inode)->lli_projid != projid)
                return -EINVAL;
@@ -4516,7 +4537,6 @@ int ll_fsync(struct file *file, loff_t start, loff_t end, int datasync)
        /* fsync's caller has already called _fdata{sync,write}, we want
         * that IO to finish before calling the osc and mdc sync methods */
        rc = filemap_write_and_wait_range(inode->i_mapping, start, end);
-       inode_lock(inode);
 
        /* catch async errors that were recorded back when async writeback
         * failed for pages in this mapping. */
@@ -4557,8 +4577,6 @@ int ll_fsync(struct file *file, loff_t start, loff_t end, int datasync)
                        fd->fd_write_failed = false;
        }
 
-       inode_unlock(inode);
-
        if (!rc)
                ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_FSYNC,
                                   ktime_us_delta(ktime_get(), kstart));
@@ -4818,6 +4836,12 @@ int ll_migrate(struct inode *parent, struct file *file, struct lmv_user_md *lum,
                               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,