Whamcloud - gitweb
LU-4712 llite: lock the inode to be migrated
[fs/lustre-release.git] / lustre / llite / file.c
index d1ca438..0ee0dde 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2013, Intel Corporation.
+ * Copyright (c) 2011, 2014, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -1014,9 +1014,9 @@ int ll_merge_attr(const struct lu_env *env, struct inode *inode)
        struct ll_inode_info *lli = ll_i2info(inode);
        struct cl_object *obj = lli->lli_clob;
        struct cl_attr *attr = ccc_env_thread_attr(env);
-       obd_time atime;
-       obd_time mtime;
-       obd_time ctime;
+       s64 atime;
+       s64 mtime;
+       s64 ctime;
        int rc = 0;
 
        ENTRY;
@@ -1052,7 +1052,7 @@ int ll_merge_attr(const struct lu_env *env, struct inode *inode)
        CDEBUG(D_VFSTRACE, DFID" updating i_size "LPU64"\n",
               PFID(&lli->lli_fid), attr->cat_size);
 
-       cl_isize_write_nolock(inode, attr->cat_size);
+       i_size_write(inode, attr->cat_size);
        inode->i_blocks = attr->cat_blocks;
 
        LTIME_S(inode->i_atime) = atime;
@@ -1153,24 +1153,24 @@ restart:
 
         if (cl_io_rw_init(env, io, iot, *ppos, count) == 0) {
                struct vvp_io *vio = vvp_env_io(env);
-               struct ccc_io *cio = ccc_env_io(env);
                bool range_locked = false;
 
                if (file->f_flags & O_APPEND)
                        range_lock_init(&range, 0, LUSTRE_EOF);
                else
                        range_lock_init(&range, *ppos, *ppos + count - 1);
-               cio->cui_fd  = LUSTRE_FPRIVATE(file);
-               vio->cui_io_subtype = args->via_io_subtype;
-
-                switch (vio->cui_io_subtype) {
-                case IO_NORMAL:
-                        cio->cui_iov = args->u.normal.via_iov;
-                        cio->cui_nrsegs = args->u.normal.via_nrsegs;
-                        cio->cui_tot_nrsegs = cio->cui_nrsegs;
-                        cio->cui_iocb = args->u.normal.via_iocb;
-                        if ((iot == CIT_WRITE) &&
-                            !(cio->cui_fd->fd_flags & LL_FILE_GROUP_LOCKED)) {
+
+               vio->vui_fd  = LUSTRE_FPRIVATE(file);
+               vio->vui_io_subtype = args->via_io_subtype;
+
+               switch (vio->vui_io_subtype) {
+               case IO_NORMAL:
+                       vio->vui_iov = args->u.normal.via_iov;
+                       vio->vui_nrsegs = args->u.normal.via_nrsegs;
+                       vio->vui_tot_nrsegs = vio->vui_nrsegs;
+                       vio->vui_iocb = args->u.normal.via_iocb;
+                       if ((iot == CIT_WRITE) &&
+                           !(vio->vui_fd->fd_flags & LL_FILE_GROUP_LOCKED)) {
                                CDEBUG(D_VFSTRACE, "Range lock "RL_FMT"\n",
                                       RL_PARA(&range));
                                result = range_lock(&lli->lli_write_tree,
@@ -1181,15 +1181,15 @@ restart:
                                range_locked = true;
                        }
                        down_read(&lli->lli_trunc_sem);
-                        break;
-                case IO_SPLICE:
-                        vio->u.splice.cui_pipe = args->u.splice.via_pipe;
-                        vio->u.splice.cui_flags = args->u.splice.via_flags;
-                        break;
-                default:
-                        CERROR("Unknow IO type - %u\n", vio->cui_io_subtype);
-                        LBUG();
-                }
+                       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 subtype %u\n", vio->vui_io_subtype);
+                       LBUG();
+               }
 
                ll_cl_add(file, env, io);
                 result = cl_io_loop(env, io);
@@ -1433,8 +1433,11 @@ int ll_lov_setstripe_ea_info(struct inode *inode, struct file *file,
                             int lum_size)
 {
        struct lov_stripe_md *lsm = NULL;
-       struct lookup_intent oit = {.it_op = IT_OPEN, .it_flags = flags};
-       int rc = 0;
+       struct lookup_intent oit = {
+               .it_op = IT_OPEN,
+               .it_flags = flags | MDS_OPEN_BY_FID,
+       };
+       int rc;
        ENTRY;
 
        lsm = ccc_inode_lsm_get(inode);
@@ -1446,13 +1449,13 @@ int ll_lov_setstripe_ea_info(struct inode *inode, struct file *file,
        }
 
        ll_inode_size_lock(inode);
-       oit.it_flags |= MDS_OPEN_BY_FID;
        rc = ll_intent_file_open(file, lum, lum_size, &oit);
-       if (rc)
+       if (rc < 0)
                GOTO(out_unlock, rc);
+
        rc = oit.d.lustre.it_status;
        if (rc < 0)
-               GOTO(out_req_free, rc);
+               GOTO(out_unlock, rc);
 
        ll_release_openhandle(file->f_dentry, &oit);
 
@@ -1462,10 +1465,8 @@ out_unlock:
        ccc_inode_lsm_put(inode, lsm);
 out:
        cl_lov_delay_create_clear(&file->f_flags);
+
        RETURN(rc);
-out_req_free:
-       ptlrpc_req_finished((struct ptlrpc_request *) oit.d.lustre.it_data);
-       goto out;
 }
 
 int ll_lov_getstripe_ea_info(struct inode *inode, const char *filename,
@@ -1653,7 +1654,7 @@ ll_get_grouplock(struct inode *inode, struct file *file, unsigned long arg)
        LASSERT(fd->fd_grouplock.cg_lock == NULL);
        spin_unlock(&lli->lli_lock);
 
-       rc = cl_get_grouplock(cl_i2info(inode)->lli_clob,
+       rc = cl_get_grouplock(ll_i2info(inode)->lli_clob,
                              arg, (file->f_flags & O_NONBLOCK), &grouplock);
        if (rc)
                RETURN(rc);
@@ -1793,6 +1794,12 @@ static int ll_do_fiemap(struct inode *inode, struct ll_user_fiemap *fiemap,
        fm_key.oa.o_oi = lsm->lsm_oi;
         fm_key.oa.o_valid = OBD_MD_FLID | OBD_MD_FLGROUP;
 
+       if (i_size_read(inode) == 0) {
+               rc = ll_glimpse_size(inode);
+               if (rc)
+                       GOTO(out, rc);
+       }
+
         obdo_from_inode(&fm_key.oa, inode, OBD_MD_FLSIZE);
         obdo_set_parent_fid(&fm_key.oa, &ll_i2info(inode)->lli_fid);
         /* If filesize is 0, then there would be no objects for mapping */
@@ -2725,7 +2732,7 @@ int cl_sync_file_range(struct inode *inode, loff_t start, loff_t end,
        capa = ll_osscapa_get(inode, CAPA_OPC_OSS_WRITE);
 
        io = ccc_env_thread_io(env);
-       io->ci_obj = cl_i2info(inode)->lli_clob;
+       io->ci_obj = ll_i2info(inode)->lli_clob;
        io->ci_ignore_layout = ignore_layout;
 
        /* initialize parameters for sync */
@@ -3023,11 +3030,14 @@ int ll_migrate(struct inode *parent, struct file *file, int mdtidx,
        qstr.name = name;
        qstr.len = namelen;
        dchild = d_lookup(file->f_dentry, &qstr);
-       if (dchild != NULL && dchild->d_inode != NULL) {
-               op_data->op_fid3 = *ll_inode2fid(dchild->d_inode);
+       if (dchild != NULL) {
                if (dchild->d_inode != NULL) {
                        child_inode = igrab(dchild->d_inode);
-                       ll_invalidate_aliases(child_inode);
+                       if (child_inode != NULL) {
+                               mutex_lock(&child_inode->i_mutex);
+                               op_data->op_fid3 = *ll_inode2fid(child_inode);
+                               ll_invalidate_aliases(child_inode);
+                       }
                }
                dput(dchild);
        } else {
@@ -3068,6 +3078,7 @@ int ll_migrate(struct inode *parent, struct file *file, int mdtidx,
 out_free:
        if (child_inode != NULL) {
                clear_nlink(child_inode);
+               mutex_unlock(&child_inode->i_mutex);
                iput(child_inode);
        }
 
@@ -3227,10 +3238,10 @@ static int __ll_inode_revalidate(struct dentry *dentry, __u64 ibits)
 
                 ll_lookup_finish_locks(&oit, dentry);
         } else if (!ll_have_md_lock(dentry->d_inode, &ibits, LCK_MINMODE)) {
-                struct ll_sb_info *sbi = ll_i2sbi(dentry->d_inode);
-                obd_valid valid = OBD_MD_FLGETATTR;
-                struct md_op_data *op_data;
-                int ealen = 0;
+               struct ll_sb_info *sbi = ll_i2sbi(dentry->d_inode);
+               u64 valid = OBD_MD_FLGETATTR;
+               struct md_op_data *op_data;
+               int ealen = 0;
 
                if (S_ISREG(inode->i_mode)) {
                        rc = ll_get_default_mdsize(sbi, &ealen);
@@ -3270,12 +3281,13 @@ static int ll_merge_md_attr(struct inode *inode)
 
        LASSERT(ll_i2info(inode)->lli_lsm_md != NULL);
        rc = md_merge_attr(ll_i2mdexp(inode), ll_i2info(inode)->lli_lsm_md,
-                          &attr);
+                          &attr, ll_md_blocking_ast);
        if (rc != 0)
                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;
@@ -3348,16 +3360,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 != NULL) {
-               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;
 }
@@ -4037,7 +4043,7 @@ int ll_layout_restore(struct inode *inode, loff_t offset, __u64 length)
        hur->hur_user_item[0].hui_extent.offset = offset;
        hur->hur_user_item[0].hui_extent.length = length;
        hur->hur_request.hr_itemcount = 1;
-       rc = obd_iocontrol(LL_IOC_HSM_REQUEST, cl_i2sbi(inode)->ll_md_exp,
+       rc = obd_iocontrol(LL_IOC_HSM_REQUEST, ll_i2sbi(inode)->ll_md_exp,
                           len, hur, NULL);
        OBD_FREE(hur, len);
        RETURN(rc);