Whamcloud - gitweb
Small fix for remote client.
authorfanyong <fanyong>
Sat, 7 Oct 2006 07:24:36 +0000 (07:24 +0000)
committerfanyong <fanyong>
Sat, 7 Oct 2006 07:24:36 +0000 (07:24 +0000)
lustre/llite/llite_lib.c
lustre/llite/remote_perm.c

index 9e20768..e919b4c 100644 (file)
@@ -163,6 +163,7 @@ static int client_common_fill_super(struct super_block *sb,
         struct lustre_handle md_conn = {0, };
         struct obd_connect_data *data = NULL;
         struct lustre_md lmd;
+        obd_valid valid;
         int size, err;
         ENTRY;
 
@@ -392,10 +393,13 @@ static int client_common_fill_super(struct super_block *sb,
 
         /* make root inode
          * XXX: move this to after cbd setup? */
-        err = md_getattr(sbi->ll_md_exp, &rootfid, oc,
-                         OBD_MD_FLGETATTR | OBD_MD_FLBLOCKS | OBD_MD_FLMDSCAPA |
-                         (sbi->ll_flags & LL_SBI_ACL ? OBD_MD_FLACL : 0),
-                         0, &request);
+        valid = OBD_MD_FLGETATTR | OBD_MD_FLBLOCKS | OBD_MD_FLMDSCAPA;
+        if (sbi->ll_flags & LL_SBI_RMT_CLIENT)
+                valid |= OBD_MD_FLRMTPERM;
+        else if (sbi->ll_flags & LL_SBI_ACL)
+                valid |= OBD_MD_FLACL;
+
+        err = md_getattr(sbi->ll_md_exp, &rootfid, oc, valid, 0, &request);
         if (oc)
                 free_capa(oc);
         if (err) {
@@ -780,6 +784,7 @@ void ll_lli_init(struct ll_inode_info *lli)
         lli->lli_open_fd_exec_count = 0;
         INIT_LIST_HEAD(&lli->lli_dead_list);
         INIT_LIST_HEAD(&lli->lli_oss_capas);
+        lli->lli_remote_perms = NULL;
         sema_init(&lli->lli_rmtperm_sem, 1);
 }
 
@@ -1229,21 +1234,21 @@ void ll_clear_inode(struct inode *inode)
                 lli->lli_symlink_name = NULL;
         }
 
+        if (sbi->ll_flags & LL_SBI_RMT_CLIENT) {
+                LASSERT(lli->lli_posix_acl == NULL);
+                if (lli->lli_remote_perms) {
+                        free_rmtperm_hash(lli->lli_remote_perms);
+                        lli->lli_remote_perms = NULL;
+                }
+        }
 #ifdef CONFIG_FS_POSIX_ACL
-        if (lli->lli_posix_acl) {
+        else if (lli->lli_posix_acl) {
                 LASSERT(atomic_read(&lli->lli_posix_acl->a_refcount) == 1);
                 LASSERT(lli->lli_remote_perms == NULL);
                 posix_acl_release(lli->lli_posix_acl);
                 lli->lli_posix_acl = NULL;
         }
 #endif
-        if (lli->lli_remote_perms) {
-                LASSERT(sbi->ll_flags & LL_SBI_RMT_CLIENT);
-                LASSERT(lli->lli_posix_acl == NULL);
-                free_rmtperm_hash(lli->lli_remote_perms);
-                lli->lli_remote_perms = NULL;
-        }
-
         lli->lli_inode_magic = LLI_INODE_DEAD;
 
         spin_lock(&sbi->ll_deathrow_lock);
@@ -1697,6 +1702,7 @@ void ll_update_inode(struct inode *inode, struct lustre_md *md)
         struct ll_inode_info *lli = ll_i2info(inode);
         struct mdt_body *body = md->body;
         struct lov_stripe_md *lsm = md->lsm;
+        struct ll_sb_info *sbi = ll_i2sbi(inode);
 
         LASSERT ((lsm != NULL) == ((body->valid & OBD_MD_FLEASIZE) != 0));
         if (lsm != NULL) {
@@ -1735,9 +1741,12 @@ void ll_update_inode(struct inode *inode, struct lustre_md *md)
                         obd_free_memmd(ll_i2dtexp(inode), &lsm);
         }
 
+        if (sbi->ll_flags & LL_SBI_RMT_CLIENT) {
+                if (body->valid & OBD_MD_FLRMTPERM)
+                        ll_update_remote_perm(inode, md->remote_perm);
+        }
 #ifdef CONFIG_FS_POSIX_ACL
-        LASSERT(!md->posix_acl || (body->valid & OBD_MD_FLACL));
-        if (body->valid & OBD_MD_FLACL) {
+        else if (body->valid & OBD_MD_FLACL) {
                 spin_lock(&lli->lli_lock);
                 if (lli->lli_posix_acl)
                         posix_acl_release(lli->lli_posix_acl);
@@ -1745,9 +1754,6 @@ void ll_update_inode(struct inode *inode, struct lustre_md *md)
                 spin_unlock(&lli->lli_lock);
         }
 #endif
-        if (body->valid & OBD_MD_FLRMTPERM)
-                ll_update_remote_perm(inode, md->remote_perm);
-
         if (body->valid & OBD_MD_FLATIME &&
             body->atime > LTIME_S(inode->i_atime))
                 LTIME_S(inode->i_atime) = body->atime;
index 4183fa6..7fdb295 100644 (file)
@@ -53,6 +53,9 @@ static inline struct ll_remote_perm *alloc_ll_remote_perm(void)
 
 static inline void free_ll_remote_perm(struct ll_remote_perm *lrp)
 {
+        if (!lrp)
+                return;
+
         if (!hlist_unhashed(&lrp->lrp_list))
                 hlist_del(&lrp->lrp_list);
         OBD_SLAB_FREE(lrp, ll_remote_perm_cachep, sizeof(*lrp));
@@ -81,6 +84,9 @@ void free_rmtperm_hash(struct hlist_head *hash)
         struct ll_remote_perm *lrp;
         struct hlist_node *node, *next;
 
+        if(!hash)
+                return;
+
         for (i = 0; i < REMOTE_PERM_HASHSIZE; i++)
                 hlist_for_each_entry_safe(lrp, node, next, hash + i, lrp_list)
                         free_ll_remote_perm(lrp);
@@ -94,7 +100,7 @@ static inline int remote_perm_hashfunc(uid_t uid)
 }
 
 /* NB: setxid permission is not checked here, instead it's done on
- * MDS when client get remote permission. (lookup/mdc_get_remote_perm). */
+ * MDT when client get remote permission. (lookup/mdc_get_remote_perm). */
 static int do_check_remote_perm(struct ll_inode_info *lli, int mask)
 {
         struct hlist_head *head;
@@ -138,7 +144,7 @@ out:
 int ll_update_remote_perm(struct inode *inode, struct mdt_remote_perm *perm)
 {
         struct ll_inode_info *lli = ll_i2info(inode);
-        struct ll_remote_perm *lrp, *tmp = NULL;
+        struct ll_remote_perm *lrp = NULL, *tmp = NULL;
         struct hlist_head *head, *perm_hash = NULL;
         struct hlist_node *node;
         ENTRY;
@@ -166,12 +172,6 @@ int ll_update_remote_perm(struct inode *inode, struct mdt_remote_perm *perm)
                 }
         }
 
-        lrp = alloc_ll_remote_perm();
-        if (!lrp) {
-                CERROR("alloc memory for ll_remote_perm failed!\n");
-                RETURN(-ENOMEM);
-        }
-
         spin_lock(&lli->lli_lock);
 
         if (!lli->lli_remote_perms)
@@ -180,6 +180,8 @@ int ll_update_remote_perm(struct inode *inode, struct mdt_remote_perm *perm)
                 free_rmtperm_hash(perm_hash);
 
         head = lli->lli_remote_perms + remote_perm_hashfunc(perm->rp_uid);
+
+again:
         hlist_for_each_entry(tmp, node, head, lrp_list) {
                 if (tmp->lrp_uid != current->uid)
                         continue;
@@ -189,11 +191,23 @@ int ll_update_remote_perm(struct inode *inode, struct mdt_remote_perm *perm)
                         continue;
                 if (tmp->lrp_fsgid != current->fsgid)
                         continue;
-                free_ll_remote_perm(lrp);
+                if (lrp)
+                        free_ll_remote_perm(lrp);
                 lrp = tmp;
                 break;
         }
 
+        if (!lrp) {
+                spin_unlock(&lli->lli_lock);
+                lrp = alloc_ll_remote_perm();
+                if (!lrp) {
+                        CERROR("alloc memory for ll_remote_perm failed!\n");
+                        RETURN(-ENOMEM);
+                }
+                spin_lock(&lli->lli_lock);
+                goto again;
+        }
+
         lrp->lrp_uid         = perm->rp_uid;
         lrp->lrp_gid         = perm->rp_gid;
         lrp->lrp_fsuid       = perm->rp_fsuid;