Whamcloud - gitweb
Branch: b_new_cmd
authorwangdi <wangdi>
Wed, 9 Aug 2006 08:31:08 +0000 (08:31 +0000)
committerwangdi <wangdi>
Wed, 9 Aug 2006 08:31:08 +0000 (08:31 +0000)
1)merge some fixes from b1_5
 *only client has parent update lock, then hash the child dentry, it could
  fix bad inode problems
 *when ll_inode_revaldate_it can not match lock locally, it should try to
  retrieve from remote server
2)re-phase comments in mdd_lov_create
3)remove LUSTRE_POSIX_MAX_ACL_SIZE from liblustre.h, it is not needed.

lustre/include/liblustre.h
lustre/llite/dcache.c
lustre/llite/file.c
lustre/llite/llite_internal.h
lustre/llite/namei.c
lustre/mdc/mdc_locks.c
lustre/mdc/mdc_request.c
lustre/mdd/mdd_lov.c

index e0b5c0f..aaa369d 100644 (file)
@@ -883,10 +883,6 @@ void posix_acl_release(struct posix_acl *acl)
 {
 }
 
-#define LUSTRE_POSIX_ACL_MAX_ENTRIES    (32)
-#define LUSTRE_POSIX_ACL_MAX_SIZE       \
-        (sizeof(xattr_acl_header) + 32 * sizeof(xattr_acl_entry))
-
 #ifndef ENOTSUPP
 #define ENOTSUPP ENOTSUP
 #endif
index ad53c20..ad565ae 100644 (file)
@@ -141,6 +141,64 @@ void ll_intent_release(struct lookup_intent *it)
         EXIT;
 }
 
+/* Drop dentry if it is not used already, unhash otherwise.
+   Should be called with dcache lock held!
+   Returns: 1 if dentry was dropped, 0 if unhashed. */
+int ll_drop_dentry(struct dentry *dentry)
+{
+        lock_dentry(dentry);
+                CDEBUG(D_DENTRY, "dentry in drop %.*s (%p) parent %p "
+                       "inode %p flags %d\n", dentry->d_name.len,
+                       dentry->d_name.name, dentry, dentry->d_parent,
+                       dentry->d_inode, dentry->d_flags);
+
+        if (atomic_read(&dentry->d_count) == 0) {
+                CDEBUG(D_DENTRY, "deleting dentry %.*s (%p) parent %p "
+                       "inode %p\n", dentry->d_name.len,
+                       dentry->d_name.name, dentry, dentry->d_parent,
+                       dentry->d_inode);
+                dget_locked(dentry);
+                __d_drop(dentry);
+                unlock_dentry(dentry);
+                spin_unlock(&dcache_lock);
+                dput(dentry);
+                spin_lock(&dcache_lock);
+                return 1;
+        }
+
+#ifdef LUSTRE_KERNEL_VERSION
+        if (!(dentry->d_flags & DCACHE_LUSTRE_INVALID)) {
+#else
+        if (!d_unhashed(dentry)) {
+                struct inode *inode = dentry->d_inode;
+#endif
+                CDEBUG(D_DENTRY, "unhashing dentry %.*s (%p) parent %p "
+                       "inode %p refc %d\n", dentry->d_name.len,
+                       dentry->d_name.name, dentry, dentry->d_parent,
+                       dentry->d_inode, atomic_read(&dentry->d_count));
+                /* actually we don't unhash the dentry, rather just
+                 * mark it inaccessible for to __d_lookup(). otherwise
+                 * sys_getcwd() could return -ENOENT -bzzz */
+#ifdef LUSTRE_KERNEL_VERSION
+                dentry->d_flags |= DCACHE_LUSTRE_INVALID;
+#else
+                if (!inode || !S_ISDIR(inode->i_mode))
+                        __d_drop(dentry);
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+                __d_drop(dentry);
+                if (inode) {
+                        /* Put positive dentries to orphan list */
+                        hlist_add_head(&dentry->d_hash,
+                                       &ll_i2sbi(inode)->ll_orphan_dentry_list);
+                }
+#endif
+        }
+        unlock_dentry(dentry);
+        return 0;
+}
+
 void ll_unhash_aliases(struct inode *inode)
 {
         struct list_head *tmp, *head;
@@ -151,16 +209,21 @@ void ll_unhash_aliases(struct inode *inode)
                 return;
         }
 
-        CDEBUG(D_INODE, "marking dentries for ino %lu/%u(%p) invalid\n",
+        CDEBUG(D_INODE, "marking dentries for 111 ino %lu/%u(%p) invalid\n",
                inode->i_ino, inode->i_generation, inode);
 
         head = &inode->i_dentry;
-restart:
         spin_lock(&dcache_lock);
+restart:
         tmp = head;
         while ((tmp = tmp->next) != head) {
                 struct dentry *dentry = list_entry(tmp, struct dentry, d_alias);
 
+                CDEBUG(D_DENTRY, "dentry in drop %.*s (%p) parent %p "
+                       "inode %p flags %d\n", dentry->d_name.len,
+                       dentry->d_name.name, dentry, dentry->d_parent,
+                       dentry->d_inode, dentry->d_flags);
+
                 if (dentry->d_name.len == 1 && dentry->d_name.name[0] == '/') {
                         CERROR("called on root (?) dentry=%p, inode=%p "
                                "ino=%lu\n", dentry, inode, inode->i_ino);
@@ -178,35 +241,9 @@ restart:
 
                         continue;
                 }
-
-                lock_dentry(dentry);
-                if (atomic_read(&dentry->d_count) == 0) {
-                        CDEBUG(D_DENTRY, "deleting dentry %.*s (%p) parent %p "
-                               "inode %p\n", dentry->d_name.len,
-                               dentry->d_name.name, dentry, dentry->d_parent,
-                               dentry->d_inode);
-                        dget_locked(dentry);
-                        __d_drop(dentry);
-                        unlock_dentry(dentry);
-                        spin_unlock(&dcache_lock);
-                        dput(dentry);
-                        goto restart;
-                } else if (!(dentry->d_flags & DCACHE_LUSTRE_INVALID)) {
-                        CDEBUG(D_DENTRY, "unhashing dentry %.*s (%p) parent %p "
-                               "inode %p refc %d\n", dentry->d_name.len,
-                               dentry->d_name.name, dentry, dentry->d_parent,
-                               dentry->d_inode, atomic_read(&dentry->d_count));
-                        /* actually we don't unhash the dentry, rather just
-                         * mark it inaccessible for to __d_lookup(). otherwise
-                         * sys_getcwd() could return -ENOENT -bzzz */
-                        dentry->d_flags |= DCACHE_LUSTRE_INVALID;
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-                        __d_drop(dentry);
-                        hlist_add_head(&dentry->d_hash,
-                                       &ll_i2sbi(inode)->ll_orphan_dentry_list);
-#endif
-                }
-                unlock_dentry(dentry);
+                
+                if (ll_drop_dentry(dentry))
+                          goto restart;
         }
         spin_unlock(&dcache_lock);
         EXIT;
index f4e1078..4fb7200 100644 (file)
@@ -1929,6 +1929,29 @@ int ll_file_flock(struct file *file, int cmd, struct file_lock *file_lock)
         RETURN(rc);
 }
 
+int ll_have_md_lock(struct inode *inode, __u64 bits)
+{
+        struct lustre_handle lockh;
+        ldlm_policy_data_t policy = { .l_inodebits = {bits}};
+        struct lu_fid *fid;
+        int flags;
+        ENTRY;
+
+        if (!inode)
+               RETURN(0);
+
+        fid = &ll_i2info(inode)->lli_fid;
+        CDEBUG(D_INFO, "trying to match res "DFID3"\n", PFID3(fid));
+
+        flags = LDLM_FL_BLOCK_GRANTED | LDLM_FL_CBPENDING | LDLM_FL_TEST_LOCK;
+        if (md_lock_match(ll_i2mdexp(inode), flags, fid, LDLM_IBITS, &policy, 
+                                LCK_CR|LCK_CW|LCK_PR, &lockh)) {
+                RETURN(1);
+        }
+
+        RETURN(0);
+}
+
 int ll_inode_revalidate_it(struct dentry *dentry, struct lookup_intent *it)
 {
         struct lookup_intent oit = { .it_op = IT_GETATTR };
@@ -1969,7 +1992,13 @@ int ll_inode_revalidate_it(struct dentry *dentry, struct lookup_intent *it)
         rc = ll_revalidate_it_finish(req, 1, &oit, dentry);
         if (rc)
                 GOTO(out, rc);
-
+        
+        if (!dentry->d_inode->i_nlink) {
+                spin_lock(&dcache_lock);
+                ll_drop_dentry(dentry);
+                spin_unlock(&dcache_lock);
+        }
+        
         ll_lookup_finish_locks(&oit, dentry);
 
         /* object is allocated, validate size */
index c41502f..92a1927 100644 (file)
@@ -382,6 +382,7 @@ extern struct file_operations ll_file_operations;
 extern struct file_operations ll_file_operations_flock;
 extern struct inode_operations ll_file_inode_operations;
 extern int ll_inode_revalidate_it(struct dentry *, struct lookup_intent *);
+extern int ll_have_md_lock(struct inode *inode, __u64 bits);
 int ll_extent_lock(struct ll_file_data *, struct inode *,
                    struct lov_stripe_md *, int mode, ldlm_policy_data_t *,
                    struct lustre_handle *, int ast_flags);
@@ -411,6 +412,7 @@ int ll_inode_permission(struct inode *inode, int mask);
 /* llite/dcache.c */
 void ll_intent_drop_lock(struct lookup_intent *);
 void ll_intent_release(struct lookup_intent *);
+int ll_drop_dentry(struct dentry *dentry);
 extern void ll_set_dd(struct dentry *de);
 void ll_unhash_aliases(struct inode *);
 void ll_frob_intent(struct lookup_intent **itp, struct lookup_intent *deft);
index 9c27050..6e83eea 100644 (file)
@@ -355,9 +355,15 @@ static int lookup_it_finish(struct ptlrpc_request *request, int offset,
                 *de = ll_find_alias(inode, *de);
         } else {
                 ENTRY;
-                spin_lock(&dcache_lock);
-                ll_d_add(*de, inode);
-                spin_unlock(&dcache_lock);
+                /* Check that parent has UPDATE lock. If there is none, we
+                 * cannot afford to hash this dentry (done by ll_d_add) as it
+                 * might get picked up later when UPDATE lock will appear */
+                if (ll_have_md_lock(parent, MDS_INODELOCK_UPDATE)) {
+                        spin_lock(&dcache_lock);
+                        ll_d_add(*de, inode);
+                        spin_unlock(&dcache_lock);
+                } else
+                        (*de)->d_inode = NULL;
         }
 
         ll_set_dd(*de);
index 6d23228..252fe91 100644 (file)
 # include <linux/pagemap.h>
 # include <linux/miscdevice.h>
 # include <linux/init.h>
-#include <linux/lustre_acl.h>
 #else
 # include <liblustre.h>
 #endif
 
+#include <linux/lustre_acl.h>
 #include <obd_class.h>
 #include <lustre_dlm.h>
 #include <lprocfs_status.h>
@@ -617,7 +617,9 @@ int mdc_intent_lock(struct obd_export *exp, struct md_op_data *op_data,
                                sizeof(lockh));
                         it->d.lustre.it_lock_mode = mode;
                 }
-                RETURN(rc);
+        
+                if (rc || op_data->namelen != 0)
+                        RETURN(rc);
         }
 
         /* lookup_it may be called only after revalidate_it has run, because
@@ -676,10 +678,11 @@ int mdc_intent_lock(struct obd_export *exp, struct md_op_data *op_data,
         /* If we were revalidating a fid/name pair, mark the intent in
          * case we fail and get called again from lookup */
         if (fid_is_sane(&op_data->fid2) &&
-                        !it_disposition(it, DISP_OPEN_CREATE)) {
+                        !it_disposition(it, DISP_OPEN_CREATE) && 
+                        !(it->it_op & IT_GETATTR)) {
                 it_set_disposition(it, DISP_ENQ_COMPLETE);
                 /* Also: did we find the same inode? */
-                if (!((it->it_create_mode & O_CREAT) || it->it_op & IT_CREAT)
+                if (!(it->it_create_mode & O_CREAT || it->it_op & IT_CREAT)
                     && memcmp(&op_data->fid2, &mdt_body->fid1,
                               sizeof(op_data->fid2)))
                         RETURN(-ESTALE);
index 9b02718..496a5f5 100644 (file)
 # include <linux/module.h>
 # include <linux/pagemap.h>
 # include <linux/miscdevice.h>
-# include <linux/lustre_acl.h>
 # include <linux/init.h>
 #else
 # include <liblustre.h>
 #endif
 
+#include <linux/lustre_acl.h>
 #include <obd_class.h>
 #include <lustre_dlm.h>
 #include <lustre_fid.h>
index 8bd37fb..058f82a 100644 (file)
@@ -442,9 +442,11 @@ int mdd_lov_create(const struct lu_context *ctxt, struct mdd_device *mdd,
                 }
                 lsm->lsm_object_id = oa->o_id;
         }
-        /*after creating the object, if the la_size is not zero. 
-         *since truncate when no lsm, we should set the size to 
-         *ost object*/
+        /*Sometimes, we may truncate some object(without lsm) 
+         *then open (with write flags)it, so creating lsm above. 
+         *The Nonzero(truncated) size should tell ost. since size 
+         *attr is in charged by OST.
+         */
         if (la->la_size) {
                 oa->o_size = la->la_size;
                 obdo_from_la(oa, la, OBD_MD_FLTYPE | OBD_MD_FLATIME |