Merge branch 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[cascardo/linux.git] / drivers / staging / lustre / lustre / llite / file.c
index 4b10260..65c945d 100644 (file)
 #include <linux/file.h>
 #include <linux/sched.h>
 #include <linux/mount.h>
-#include "llite_internal.h"
 #include "../include/lustre/ll_fiemap.h"
 #include "../include/lustre/lustre_ioctl.h"
 
 #include "../include/cl_object.h"
+#include "llite_internal.h"
 
 static int
 ll_put_grouplock(struct inode *inode, struct file *file, unsigned long arg);
@@ -189,12 +189,6 @@ static int ll_close_inode_openhandle(struct obd_export *md_exp,
                spin_unlock(&lli->lli_lock);
        }
 
-       if (rc == 0) {
-               rc = ll_objects_destroy(req, inode);
-               if (rc)
-                       CERROR("inode %lu ll_objects destroy: rc = %d\n",
-                              inode->i_ino, rc);
-       }
        if (rc == 0 && op_data->op_bias & MDS_HSM_RELEASE) {
                struct mdt_body *body;
 
@@ -895,7 +889,6 @@ static int ll_lease_close(struct obd_client_handle *och, struct inode *inode,
 {
        struct ldlm_lock *lock;
        bool cancelled = true;
-       int rc;
 
        lock = ldlm_handle2lock(&och->och_lease_handle);
        if (lock) {
@@ -913,9 +906,8 @@ static int ll_lease_close(struct obd_client_handle *och, struct inode *inode,
        if (lease_broken)
                *lease_broken = cancelled;
 
-       rc = ll_close_inode_openhandle(ll_i2sbi(inode)->ll_md_exp, inode, och,
-                                      NULL);
-       return rc;
+       return ll_close_inode_openhandle(ll_i2sbi(inode)->ll_md_exp,
+                                        inode, och, NULL);
 }
 
 /* Fills the obdo with the attributes for the lsm */
@@ -1129,8 +1121,8 @@ ll_file_io_generic(const struct lu_env *env, struct vvp_io_args *args,
        struct cl_io     *io;
        ssize_t        result;
 
-       CDEBUG(D_VFSTRACE, "file: %s, type: %d ppos: %llu, count: %zd\n",
-              file->f_path.dentry->d_name.name, iot, *ppos, count);
+       CDEBUG(D_VFSTRACE, "file: %pD, type: %d ppos: %llu, count: %zu\n",
+              file, iot, *ppos, count);
 
 restart:
        io = vvp_env_thread_io(env);
@@ -1146,45 +1138,31 @@ restart:
                        range_lock_init(&range, *ppos, *ppos + count - 1);
 
                vio->vui_fd  = LUSTRE_FPRIVATE(file);
-               vio->vui_io_subtype = args->via_io_subtype;
+               vio->vui_iter = args->u.normal.via_iter;
+               vio->vui_iocb = args->u.normal.via_iocb;
+               /*
+                * Direct IO reads must also take range lock,
+                * or multiple reads will try to work on the same pages
+                * See LU-6227 for details.
+                */
+               if (((iot == CIT_WRITE) ||
+                    (iot == CIT_READ && (file->f_flags & O_DIRECT))) &&
+                   !(vio->vui_fd->fd_flags & LL_FILE_GROUP_LOCKED)) {
+                       CDEBUG(D_VFSTRACE, "Range lock [%llu, %llu]\n",
+                              range.rl_node.in_extent.start,
+                              range.rl_node.in_extent.end);
+                       result = range_lock(&lli->lli_write_tree,
+                                           &range);
+                       if (result < 0)
+                               goto out;
 
-               switch (vio->vui_io_subtype) {
-               case IO_NORMAL:
-                       vio->vui_iter = args->u.normal.via_iter;
-                       vio->vui_iocb = args->u.normal.via_iocb;
-                       /*
-                        * Direct IO reads must also take range lock,
-                        * or multiple reads will try to work on the same pages
-                        * See LU-6227 for details.
-                        */
-                       if (((iot == CIT_WRITE) ||
-                            (iot == CIT_READ && (file->f_flags & O_DIRECT))) &&
-                           !(vio->vui_fd->fd_flags & LL_FILE_GROUP_LOCKED)) {
-                               CDEBUG(D_VFSTRACE, "Range lock [%llu, %llu]\n",
-                                      range.rl_node.in_extent.start,
-                                      range.rl_node.in_extent.end);
-                               result = range_lock(&lli->lli_write_tree,
-                                                   &range);
-                               if (result < 0)
-                                       goto out;
-
-                               range_locked = true;
-                       }
-                       down_read(&lli->lli_trunc_sem);
-                       break;
-               case IO_SPLICE:
-                       vio->u.splice.vui_pipe = args->u.splice.via_pipe;
-                       vio->u.splice.vui_flags = args->u.splice.via_flags;
-                       break;
-               default:
-                       CERROR("Unknown IO type - %u\n", vio->vui_io_subtype);
-                       LBUG();
+                       range_locked = true;
                }
+               down_read(&lli->lli_trunc_sem);
                ll_cl_add(file, env, io);
                result = cl_io_loop(env, io);
                ll_cl_remove(file, env);
-               if (args->via_io_subtype == IO_NORMAL)
-                       up_read(&lli->lli_trunc_sem);
+               up_read(&lli->lli_trunc_sem);
                if (range_locked) {
                        CDEBUG(D_VFSTRACE, "Range unlock [%llu, %llu]\n",
                               range.rl_node.in_extent.start,
@@ -1207,7 +1185,7 @@ out:
         * short read/write instead of restart io.
         */
        if ((result == 0 || result == -ENODATA) && io->ci_need_restart) {
-               CDEBUG(D_VFSTRACE, "Restart %s on %pD from %lld, count:%zd\n",
+               CDEBUG(D_VFSTRACE, "Restart %s on %pD from %lld, count:%zu\n",
                       iot == CIT_READ ? "read" : "write",
                       file, *ppos, count);
                LASSERTF(io->ci_nob == 0, "%zd\n", io->ci_nob);
@@ -1243,7 +1221,7 @@ static ssize_t ll_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
        if (IS_ERR(env))
                return PTR_ERR(env);
 
-       args = ll_env_args(env, IO_NORMAL);
+       args = ll_env_args(env);
        args->u.normal.via_iter = to;
        args->u.normal.via_iocb = iocb;
 
@@ -1267,7 +1245,7 @@ static ssize_t ll_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
        if (IS_ERR(env))
                return PTR_ERR(env);
 
-       args = ll_env_args(env, IO_NORMAL);
+       args = ll_env_args(env);
        args->u.normal.via_iter = from;
        args->u.normal.via_iocb = iocb;
 
@@ -1277,37 +1255,15 @@ static ssize_t ll_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
        return result;
 }
 
-/*
- * Send file content (through pagecache) somewhere with helper
- */
-static ssize_t ll_file_splice_read(struct file *in_file, loff_t *ppos,
-                                  struct pipe_inode_info *pipe, size_t count,
-                                  unsigned int flags)
-{
-       struct lu_env      *env;
-       struct vvp_io_args *args;
-       ssize_t      result;
-       int              refcheck;
-
-       env = cl_env_get(&refcheck);
-       if (IS_ERR(env))
-               return PTR_ERR(env);
-
-       args = ll_env_args(env, IO_SPLICE);
-       args->u.splice.via_pipe = pipe;
-       args->u.splice.via_flags = flags;
-
-       result = ll_file_io_generic(env, args, in_file, CIT_READ, ppos, count);
-       cl_env_put(env, &refcheck);
-       return result;
-}
-
 int ll_lov_setstripe_ea_info(struct inode *inode, struct dentry *dentry,
                             __u64 flags, struct lov_user_md *lum,
                             int lum_size)
 {
        struct lov_stripe_md *lsm = NULL;
-       struct lookup_intent oit = {.it_op = IT_OPEN, .it_flags = flags};
+       struct lookup_intent oit = {
+               .it_op = IT_OPEN,
+               .it_flags = flags | MDS_OPEN_BY_FID,
+       };
        int rc = 0;
 
        lsm = ccc_inode_lsm_get(inode);
@@ -1320,13 +1276,12 @@ int ll_lov_setstripe_ea_info(struct inode *inode, struct dentry *dentry,
        }
 
        ll_inode_size_lock(inode);
-       oit.it_flags |= MDS_OPEN_BY_FID;
        rc = ll_intent_file_open(dentry, lum, lum_size, &oit);
-       if (rc)
+       if (rc < 0)
                goto out_unlock;
        rc = oit.it_status;
        if (rc < 0)
-               goto out_req_free;
+               goto out_unlock;
 
        ll_release_openhandle(inode, &oit);
 
@@ -1336,9 +1291,6 @@ out_unlock:
        ccc_inode_lsm_put(inode, lsm);
 out:
        return rc;
-out_req_free:
-       ptlrpc_req_finished((struct ptlrpc_request *)oit.it_request);
-       goto out;
 }
 
 int ll_lov_getstripe_ea_info(struct inode *inode, const char *filename,
@@ -1455,6 +1407,22 @@ static int ll_lov_setea(struct inode *inode, struct file *file,
        return rc;
 }
 
+static int ll_file_getstripe(struct inode *inode,
+                            struct lov_user_md __user *lum)
+{
+       struct lu_env *env;
+       int refcheck;
+       int rc;
+
+       env = cl_env_get(&refcheck);
+       if (IS_ERR(env))
+               return PTR_ERR(env);
+
+       rc = cl_object_getstripe(env, ll_i2info(inode)->lli_clob, lum);
+       cl_env_put(env, &refcheck);
+       return rc;
+}
+
 static int ll_lov_setstripe(struct inode *inode, struct file *file,
                            unsigned long arg)
 {
@@ -1472,35 +1440,18 @@ static int ll_lov_setstripe(struct inode *inode, struct file *file,
                                      lum_size);
        cl_lov_delay_create_clear(&file->f_flags);
        if (rc == 0) {
-               struct lov_stripe_md *lsm;
                __u32 gen;
 
                put_user(0, &lum->lmm_stripe_count);
 
                ll_layout_refresh(inode, &gen);
-               lsm = ccc_inode_lsm_get(inode);
-               rc = obd_iocontrol(LL_IOC_LOV_GETSTRIPE, ll_i2dtexp(inode),
-                                  0, lsm, lum);
-               ccc_inode_lsm_put(inode, lsm);
+               rc = ll_file_getstripe(inode, (struct lov_user_md __user *)arg);
        }
 
        kfree(klum);
        return rc;
 }
 
-static int ll_lov_getstripe(struct inode *inode, unsigned long arg)
-{
-       struct lov_stripe_md *lsm;
-       int rc = -ENODATA;
-
-       lsm = ccc_inode_lsm_get(inode);
-       if (lsm)
-               rc = obd_iocontrol(LL_IOC_LOV_GETSTRIPE, ll_i2dtexp(inode), 0,
-                                  lsm, (void __user *)arg);
-       ccc_inode_lsm_put(inode, lsm);
-       return rc;
-}
-
 static int
 ll_get_grouplock(struct inode *inode, struct file *file, unsigned long arg)
 {
@@ -2239,7 +2190,8 @@ ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                return rc;
        }
        case LL_IOC_LOV_GETSTRIPE:
-               return ll_lov_getstripe(inode, arg);
+               return ll_file_getstripe(inode,
+                                        (struct lov_user_md __user *)arg);
        case FSFILT_IOC_FIEMAP:
                return ll_ioctl_fiemap(inode, arg);
        case FSFILT_IOC_GETFLAGS:
@@ -2496,9 +2448,8 @@ static loff_t ll_file_seek(struct file *file, loff_t offset, int origin)
                eof = i_size_read(inode);
        }
 
-       retval = generic_file_llseek_size(file, offset, origin,
-                                         ll_file_maxbytes(inode), eof);
-       return retval;
+       return generic_file_llseek_size(file, offset, origin,
+                                       ll_file_maxbytes(inode), eof);
 }
 
 static int ll_flush(struct file *file, fl_owner_t id)
@@ -2809,11 +2760,15 @@ int ll_migrate(struct inode *parent, struct file *file, int mdtidx,
        qstr.name = name;
        qstr.len = namelen;
        dchild = d_lookup(file_dentry(file), &qstr);
-       if (dchild && dchild->d_inode) {
+       if (dchild) {
                op_data->op_fid3 = *ll_inode2fid(dchild->d_inode);
                if (dchild->d_inode) {
                        child_inode = igrab(dchild->d_inode);
-                       ll_invalidate_aliases(child_inode);
+                       if (child_inode) {
+                               inode_lock(child_inode);
+                               op_data->op_fid3 = *ll_inode2fid(child_inode);
+                               ll_invalidate_aliases(child_inode);
+                       }
                }
                dput(dchild);
        } else {
@@ -2854,6 +2809,7 @@ int ll_migrate(struct inode *parent, struct file *file, int mdtidx,
 out_free:
        if (child_inode) {
                clear_nlink(child_inode);
+               inode_unlock(child_inode);
                iput(child_inode);
        }
 
@@ -2924,15 +2880,12 @@ enum ldlm_mode ll_take_md_lock(struct inode *inode, __u64 bits,
 {
        ldlm_policy_data_t policy = { .l_inodebits = {bits} };
        struct lu_fid *fid;
-       enum ldlm_mode rc;
 
        fid = &ll_i2info(inode)->lli_fid;
        CDEBUG(D_INFO, "trying to match res "DFID"\n", PFID(fid));
 
-       rc = md_lock_match(ll_i2mdexp(inode), flags | LDLM_FL_BLOCK_GRANTED,
-                          fid, LDLM_IBITS, &policy, mode, lockh);
-
-       return rc;
+       return md_lock_match(ll_i2mdexp(inode), flags | LDLM_FL_BLOCK_GRANTED,
+                            fid, LDLM_IBITS, &policy, mode, lockh);
 }
 
 static int ll_inode_revalidate_fini(struct inode *inode, int rc)
@@ -3033,10 +2986,8 @@ static int __ll_inode_revalidate(struct dentry *dentry, __u64 ibits)
                op_data->op_valid = valid;
                rc = md_getattr(sbi->ll_md_exp, op_data, &req);
                ll_finish_md_op_data(op_data);
-               if (rc) {
-                       rc = ll_inode_revalidate_fini(inode, rc);
-                       return rc;
-               }
+               if (rc)
+                       return ll_inode_revalidate_fini(inode, rc);
 
                rc = ll_prep_inode(&inode, req, NULL, NULL);
        }
@@ -3052,12 +3003,13 @@ static int ll_merge_md_attr(struct inode *inode)
 
        LASSERT(ll_i2info(inode)->lli_lsm_md);
        rc = md_merge_attr(ll_i2mdexp(inode), ll_i2info(inode)->lli_lsm_md,
-                          &attr);
+                          &attr, ll_md_blocking_ast);
        if (rc)
                return rc;
 
-       ll_i2info(inode)->lli_stripe_dir_size = attr.cat_size;
-       ll_i2info(inode)->lli_stripe_dir_nlink = attr.cat_nlink;
+       set_nlink(inode, attr.cat_nlink);
+       inode->i_blocks = attr.cat_blocks;
+       i_size_write(inode, attr.cat_size);
 
        ll_i2info(inode)->lli_atime = attr.cat_atime;
        ll_i2info(inode)->lli_mtime = attr.cat_mtime;
@@ -3130,16 +3082,10 @@ int ll_getattr(struct vfsmount *mnt, struct dentry *de, struct kstat *stat)
        stat->mtime = inode->i_mtime;
        stat->ctime = inode->i_ctime;
        stat->blksize = 1 << inode->i_blkbits;
-       stat->blocks = inode->i_blocks;
 
-       if (S_ISDIR(inode->i_mode) &&
-           ll_i2info(inode)->lli_lsm_md) {
-               stat->nlink = lli->lli_stripe_dir_nlink;
-               stat->size = lli->lli_stripe_dir_size;
-       } else {
-               stat->nlink = inode->i_nlink;
-               stat->size = i_size_read(inode);
-       }
+       stat->nlink = inode->i_nlink;
+       stat->size = i_size_read(inode);
+       stat->blocks = inode->i_blocks;
 
        return 0;
 }
@@ -3282,7 +3228,7 @@ struct file_operations ll_file_operations = {
        .release        = ll_file_release,
        .mmap      = ll_file_mmap,
        .llseek  = ll_file_seek,
-       .splice_read    = ll_file_splice_read,
+       .splice_read    = generic_file_splice_read,
        .fsync    = ll_fsync,
        .flush    = ll_flush
 };
@@ -3295,7 +3241,7 @@ struct file_operations ll_file_operations_flock = {
        .release        = ll_file_release,
        .mmap      = ll_file_mmap,
        .llseek  = ll_file_seek,
-       .splice_read    = ll_file_splice_read,
+       .splice_read    = generic_file_splice_read,
        .fsync    = ll_fsync,
        .flush    = ll_flush,
        .flock    = ll_file_flock,
@@ -3311,7 +3257,7 @@ struct file_operations ll_file_operations_noflock = {
        .release        = ll_file_release,
        .mmap      = ll_file_mmap,
        .llseek  = ll_file_seek,
-       .splice_read    = ll_file_splice_read,
+       .splice_read    = generic_file_splice_read,
        .fsync    = ll_fsync,
        .flush    = ll_flush,
        .flock    = ll_file_noflock,