Whamcloud - gitweb
LU-1842 ldlm: support for sending GL ASTs to multiple locks
[fs/lustre-release.git] / lustre / obdfilter / filter.c
index eb74491..ef25f36 100644 (file)
@@ -1418,8 +1418,8 @@ obd_id filter_last_id(struct filter_obd *filter, obd_seq group)
 
 static int filter_lock_dentry(struct obd_device *obd, struct dentry *dparent)
 {
-        LOCK_INODE_MUTEX_PARENT(dparent->d_inode);
-        return 0;
+       mutex_lock_nested(&dparent->d_inode->i_mutex, I_MUTEX_PARENT);
+       return 0;
 }
 
 /* We never dget the object parent, so DON'T dput it either */
@@ -1459,7 +1459,7 @@ struct dentry *filter_parent_lock(struct obd_device *obd, obd_seq group,
 /* We never dget the object parent, so DON'T dput it either */
 static void filter_parent_unlock(struct dentry *dparent)
 {
-        UNLOCK_INODE_MUTEX(dparent->d_inode);
+       mutex_unlock(&dparent->d_inode->i_mutex);
 }
 
 /* How to get files, dentries, inodes from object id's.
@@ -1568,9 +1568,9 @@ int filter_vfs_unlink(struct inode *dir, struct dentry *dentry,
 
         /* don't need dir->i_zombie for 2.4, it is for rename/unlink of dir
          * itself we already hold dir->i_mutex for child create/unlink ops */
-        LASSERT(dentry->d_inode != NULL);
-        LASSERT(TRYLOCK_INODE_MUTEX(dir) == 0);
-        LASSERT(TRYLOCK_INODE_MUTEX(dentry->d_inode) == 0);
+       LASSERT(dentry->d_inode != NULL);
+       LASSERT(mutex_trylock(&dir->i_mutex) == 0);
+       LASSERT(mutex_trylock(&dentry->d_inode->i_mutex) == 0);
 
 
         /* may_delete() */
@@ -1599,12 +1599,12 @@ int filter_vfs_unlink(struct inode *dir, struct dentry *dentry,
 
         rc = dir->i_op->unlink(dir, dentry);
 out:
-        /* need to drop i_mutex before we lose inode reference */
-        UNLOCK_INODE_MUTEX(dentry->d_inode);
-        if (rc == 0)
-                d_delete(dentry);
+       /* need to drop i_mutex before we lose inode reference */
+       mutex_unlock(&dentry->d_inode->i_mutex);
+       if (rc == 0)
+               d_delete(dentry);
 
-        RETURN(rc);
+       RETURN(rc);
 }
 
 /* Caller must hold LCK_PW on parent and push us into kernel context.
@@ -1698,6 +1698,8 @@ static int filter_intent_policy(struct ldlm_namespace *ns,
         __u32 repsize[3] = { [MSG_PTLRPC_BODY_OFF] = sizeof(struct ptlrpc_body),
                            [DLM_LOCKREPLY_OFF]   = sizeof(*rep),
                            [DLM_REPLY_REC_OFF]   = sizeof(*reply_lvb) };
+       struct ldlm_glimpse_work        gl_work;
+       CFS_LIST_HEAD(gl_list);
         ENTRY;
 
         policy = ldlm_get_processing_policy(res);
@@ -1820,7 +1822,21 @@ static int filter_intent_policy(struct ldlm_namespace *ns,
         }
 
         LASSERTF(l->l_glimpse_ast != NULL, "l == %p", l);
-        rc = l->l_glimpse_ast(l, NULL); /* this will update the LVB */
+
+       /* Populate the gl_work structure.
+        * Grab additional reference on the lock which will be released in
+        * ldlm_work_gl_ast_lock() */
+       gl_work.gl_lock = LDLM_LOCK_GET(l);
+       /* The glimpse callback is sent to one single extent lock. As a result,
+        * the gl_work list is just composed of one element */
+       cfs_list_add_tail(&gl_work.gl_list, &gl_list);
+       /* the ldlm_glimpse_work structure is allocated on the stack */
+       gl_work.gl_flags = LDLM_GL_WORK_NOFREE;
+
+       rc = ldlm_glimpse_locks(res, &gl_list); /* this will update the LVB */
+
+       if (!cfs_list_empty(&gl_list))
+               LDLM_LOCK_RELEASE(l);
 
         lock_res(res);
         *reply_lvb = *res_lvb;
@@ -2054,7 +2070,7 @@ int filter_common_setup(struct obd_device *obd, struct lustre_cfg* lcfg,
                    lcfg bufs 1, 2, 4 (device, fstype, mount opts) are ignored.*/
                 struct lustre_sb_info *lsi = s2lsi(lmi->lmi_sb);
                 mnt = lmi->lmi_mnt;
-                obd->obd_fsops = fsfilt_get_ops(MT_STR(lsi->lsi_ldd));
+               obd->obd_fsops = fsfilt_get_ops(lsi->lsi_fstype);
         } else {
                 /* old path - used by lctl */
                 CERROR("Using old MDS mount method\n");
@@ -3213,7 +3229,7 @@ struct dentry *__filter_oa2dentry(struct obd_device *obd, struct ost_id *ostid,
                 RETURN(ERR_PTR(-ENOENT));
         }
 
-#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2,7,50,0)
+#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 7, 50, 0)
         /* Try to correct for a bug in 2.1.0 (LU-221) that caused negative
          * timestamps to appear to be in the far future, due old timestamp
          * being stored on disk as an unsigned value.  This fixes up any
@@ -3341,17 +3357,17 @@ int filter_setattr_internal(struct obd_export *exp, struct dentry *dentry,
                 if (fcc != NULL)
                         *fcc = oa->o_lcookie;
         }
-        if (ia_valid & (ATTR_SIZE | ATTR_UID | ATTR_GID)) {
-                unsigned long now = jiffies;
-                /* Filter truncates and writes are serialized by
-                 * i_alloc_sem, see the comment in
-                 * filter_preprw_write.*/
-                if (ia_valid & ATTR_SIZE)
-                        down_write(&inode->i_alloc_sem);
-                LOCK_INODE_MUTEX(inode);
-                fsfilt_check_slow(exp->exp_obd, now, "i_alloc_sem and i_mutex");
-                old_size = i_size_read(inode);
-        }
+       if (ia_valid & (ATTR_SIZE | ATTR_UID | ATTR_GID)) {
+               unsigned long now = jiffies;
+               /* Filter truncates and writes are serialized by
+                * i_alloc_sem, see the comment in
+                * filter_preprw_write.*/
+               if (ia_valid & ATTR_SIZE)
+                       down_write(&inode->i_alloc_sem);
+               mutex_lock(&inode->i_mutex);
+               fsfilt_check_slow(exp->exp_obd, now, "i_alloc_sem and i_mutex");
+               old_size = i_size_read(inode);
+       }
 
         /* VBR: version recovery check */
         rc = filter_version_get_check(exp, oti, inode);
@@ -3470,12 +3486,12 @@ out_unlock:
         if (page)
                 page_cache_release(page);
 
-        if (ia_valid & (ATTR_SIZE | ATTR_UID | ATTR_GID))
-                UNLOCK_INODE_MUTEX(inode);
-        if (ia_valid & ATTR_SIZE)
-                up_write(&inode->i_alloc_sem);
-        if (fcc)
-                OBD_FREE(fcc, sizeof(*fcc));
+       if (ia_valid & (ATTR_SIZE | ATTR_UID | ATTR_GID))
+               mutex_unlock(&inode->i_mutex);
+       if (ia_valid & ATTR_SIZE)
+               up_write(&inode->i_alloc_sem);
+       if (fcc)
+               OBD_FREE(fcc, sizeof(*fcc));
 
         /* trigger quota release */
         if (ia_valid & (ATTR_SIZE | ATTR_UID | ATTR_GID)) {
@@ -4274,7 +4290,7 @@ int filter_destroy(const struct lu_env *env, struct obd_export *exp,
                         }
                         fcc = &oa->o_lcookie;
                         ctxt = llog_group_get_ctxt(olg, fcc->lgc_subsys + 1);
-                        llog_cancel(ctxt, NULL, 1, fcc, 0);
+                       llog_cancel(NULL, ctxt, NULL, 1, fcc, 0);
                         llog_ctxt_put(ctxt);
                         fcc = NULL; /* we didn't allocate fcc, don't free it */
                 }
@@ -4304,40 +4320,40 @@ int filter_destroy(const struct lu_env *env, struct obd_export *exp,
          * between page lock, i_mutex & starting new journal handle.
          * (see bug 20321) -johann
          */
-        now = jiffies;
-        down_write(&dchild->d_inode->i_alloc_sem);
-        LOCK_INODE_MUTEX(dchild->d_inode);
-        fsfilt_check_slow(exp->exp_obd, now, "i_alloc_sem and i_mutex");
+       now = jiffies;
+       down_write(&dchild->d_inode->i_alloc_sem);
+       mutex_lock(&dchild->d_inode->i_mutex);
+       fsfilt_check_slow(exp->exp_obd, now, "i_alloc_sem and i_mutex");
+
+       /* VBR: version recovery check */
+       rc = filter_version_get_check(exp, oti, dchild->d_inode);
+       if (rc) {
+               mutex_unlock(&dchild->d_inode->i_mutex);
+               up_write(&dchild->d_inode->i_alloc_sem);
+               GOTO(cleanup, rc);
+       }
 
-        /* VBR: version recovery check */
-        rc = filter_version_get_check(exp, oti, dchild->d_inode);
-        if (rc) {
-                UNLOCK_INODE_MUTEX(dchild->d_inode);
-                up_write(&dchild->d_inode->i_alloc_sem);
-                GOTO(cleanup, rc);
-        }
+       handle = fsfilt_start_log(obd, dchild->d_inode, FSFILT_OP_SETATTR,
+                                 NULL, 1);
+       if (IS_ERR(handle)) {
+               mutex_unlock(&dchild->d_inode->i_mutex);
+               up_write(&dchild->d_inode->i_alloc_sem);
+               GOTO(cleanup, rc = PTR_ERR(handle));
+       }
 
-        handle = fsfilt_start_log(obd, dchild->d_inode, FSFILT_OP_SETATTR,
-                                  NULL, 1);
-        if (IS_ERR(handle)) {
-                UNLOCK_INODE_MUTEX(dchild->d_inode);
-                up_write(&dchild->d_inode->i_alloc_sem);
-                GOTO(cleanup, rc = PTR_ERR(handle));
-        }
+       /* Locking order: i_mutex -> journal_lock -> dqptr_sem. LU-952 */
+       ll_vfs_dq_init(dchild->d_inode);
 
-        /* Locking order: i_mutex -> journal_lock -> dqptr_sem. LU-952 */
-        ll_vfs_dq_init(dchild->d_inode);
-
-        iattr.ia_valid = ATTR_SIZE;
-        iattr.ia_size = 0;
-        rc = fsfilt_setattr(obd, dchild, handle, &iattr, 1);
-        rc2 = fsfilt_commit(obd, dchild->d_inode, handle, 0);
-        UNLOCK_INODE_MUTEX(dchild->d_inode);
-        up_write(&dchild->d_inode->i_alloc_sem);
-        if (rc)
-                GOTO(cleanup, rc);
-        if (rc2)
-                GOTO(cleanup, rc = rc2);
+       iattr.ia_valid = ATTR_SIZE;
+       iattr.ia_size = 0;
+       rc = fsfilt_setattr(obd, dchild, handle, &iattr, 1);
+       rc2 = fsfilt_commit(obd, dchild->d_inode, handle, 0);
+       mutex_unlock(&dchild->d_inode->i_mutex);
+       up_write(&dchild->d_inode->i_alloc_sem);
+       if (rc)
+               GOTO(cleanup, rc);
+       if (rc2)
+               GOTO(cleanup, rc = rc2);
 
         /* We don't actually need to lock the parent until we are unlinking
          * here, and not while truncating above.  That avoids holding the
@@ -4348,13 +4364,14 @@ int filter_destroy(const struct lu_env *env, struct obd_export *exp,
                 GOTO(cleanup, rc = PTR_ERR(dparent));
         cleanup_phase = 3; /* filter_parent_unlock */
 
-        LOCK_INODE_MUTEX(dchild->d_inode);
-        handle = fsfilt_start_log(obd, dparent->d_inode,FSFILT_OP_UNLINK,oti,1);
-        if (IS_ERR(handle)) {
-                UNLOCK_INODE_MUTEX(dchild->d_inode);
-                GOTO(cleanup, rc = PTR_ERR(handle));
-        }
-        cleanup_phase = 4; /* fsfilt_commit */
+       mutex_lock(&dchild->d_inode->i_mutex);
+       handle = fsfilt_start_log(obd, dparent->d_inode,
+                                 FSFILT_OP_UNLINK, oti, 1);
+       if (IS_ERR(handle)) {
+               mutex_unlock(&dchild->d_inode->i_mutex);
+               GOTO(cleanup, rc = PTR_ERR(handle));
+       }
+       cleanup_phase = 4; /* fsfilt_commit */
 
         /* Quota release need uid/gid of inode */
         obdo_from_inode(oa, dchild->d_inode, OBD_MD_FLUID | OBD_MD_FLGID);
@@ -4472,21 +4489,21 @@ static int filter_sync(const struct lu_env *env, struct obd_export *exp,
 
         push_ctxt(&saved, &exp->exp_obd->obd_lvfs_ctxt, NULL);
 
-        LOCK_INODE_MUTEX(dentry->d_inode);
+       mutex_lock(&dentry->d_inode->i_mutex);
 
-        rc = filemap_fdatawrite(dentry->d_inode->i_mapping);
-        if (rc == 0) {
-                /* just any file to grab fsync method - "file" arg unused */
-                struct file *file = obt->obt_rcvd_filp;
+       rc = filemap_fdatawrite(dentry->d_inode->i_mapping);
+       if (rc == 0) {
+               /* just any file to grab fsync method - "file" arg unused */
+               struct file *file = obt->obt_rcvd_filp;
 
-                if (file->f_op && file->f_op->fsync)
-                        rc = file->f_op->fsync(NULL, dentry, 1);
+               if (file->f_op && file->f_op->fsync)
+                       rc = file->f_op->fsync(NULL, dentry, 1);
 
-                rc2 = filemap_fdatawait(dentry->d_inode->i_mapping);
-                if (!rc)
-                        rc = rc2;
-        }
-        UNLOCK_INODE_MUTEX(dentry->d_inode);
+               rc2 = filemap_fdatawait(dentry->d_inode->i_mapping);
+               if (!rc)
+                       rc = rc2;
+       }
+       mutex_unlock(&dentry->d_inode->i_mutex);
 
         oinfo->oi_oa->o_valid = OBD_MD_FLID;
         obdo_from_inode(oinfo->oi_oa, dentry->d_inode, FILTER_VALID_FLAGS);