Whamcloud - gitweb
More sanity check for nlink of file.
authorfanyong <fanyong>
Wed, 22 Nov 2006 14:55:39 +0000 (14:55 +0000)
committerfanyong <fanyong>
Wed, 22 Nov 2006 14:55:39 +0000 (14:55 +0000)
lustre/cmm/cmm_object.c
lustre/include/lustre/lustre_idl.h
lustre/mdd/mdd_dir.c
lustre/mdd/mdd_internal.h
lustre/mdd/mdd_permission.c
lustre/mdt/mdt_reint.c

index ab6f552..ac0d330 100644 (file)
@@ -893,7 +893,8 @@ static int cmr_create(const struct lu_env *env, struct md_object *mo_p,
 #endif
 
         /* Local permission check for name_insert before remote ops. */
-        rc = mo_permission(env, md_object_next(mo_p), MAY_WRITE);
+        rc = mo_permission(env, md_object_next(mo_p), MAY_WRITE |
+                           (S_ISDIR(ma->ma_attr.la_mode) ? MAY_LINK : 0));
         if (rc)
                 RETURN(rc);
 
index 9015553..9ee7f14 100644 (file)
@@ -1228,6 +1228,9 @@ extern void lustre_swab_mdt_rec_setattr (struct mdt_rec_setattr *sa);
 #define MDS_OPEN_HAS_EA      010000000000 /* specify object create pattern */
 #define MDS_OPEN_HAS_OBJS    020000000000 /* Just set the EA the obj exist */
 
+/* permission for increase nlink of a file */
+#define MAY_LINK        64
+
 enum {
         MDS_CHECK_SPLIT = 1 << 0,
         MDS_CROSS_REF   = 1 << 1
index 8be0b93..1a586d3 100644 (file)
@@ -274,6 +274,8 @@ static int mdd_may_delete(const struct lu_env *env,
 int mdd_link_sanity_check(const struct lu_env *env, struct mdd_object *tgt_obj,
                           struct mdd_object *src_obj)
 {
+        struct lu_attr *la = &mdd_env_info(env)->mti_la;
+        struct mdd_device *m = mdd_obj2mdd_dev(src_obj);
         int rc = 0;
         ENTRY;
 
@@ -290,7 +292,14 @@ int mdd_link_sanity_check(const struct lu_env *env, struct mdd_object *tgt_obj,
                         RETURN(rc);
         }
 
-        RETURN(rc);
+        rc = mdd_la_get(env, src_obj, la, BYPASS_CAPA);
+        if (rc)
+                RETURN(rc);
+
+        if (la->la_nlink >= m->mdd_dt_conf.ddp_max_nlink)
+                RETURN(-EMLINK);
+        else
+                RETURN(0);
 }
 
 const struct dt_rec *__mdd_fid_rec(const struct lu_env *env,
@@ -783,6 +792,18 @@ static int mdd_rt_sanity_check(const struct lu_env *env,
                 rc = mdd_may_create(env, tgt_pobj, NULL, 1);
         }
 
+        if (!rc && src_is_dir) {
+                struct lu_attr *la = &mdd_env_info(env)->mti_la;
+                struct mdd_device *m = mdd_obj2mdd_dev(tgt_pobj);
+
+                rc = mdd_la_get(env, tgt_pobj, la, BYPASS_CAPA);
+                if (rc)
+                        RETURN(rc);
+
+                if (la->la_nlink >= m->mdd_dt_conf.ddp_max_nlink)
+                        RETURN(-EMLINK);
+        }
+
         RETURN(rc);
 }
 
@@ -1379,6 +1400,18 @@ static int mdd_rename_sanity_check(const struct lu_env *env,
                                 rc = -ENOTEMPTY;
         }
 
+        if (!rc && src_is_dir && (src_pobj != tgt_pobj)) {
+                struct lu_attr *la = &mdd_env_info(env)->mti_la;
+                struct mdd_device *m = mdd_obj2mdd_dev(tgt_pobj);
+
+                rc = mdd_la_get(env, tgt_pobj, la, BYPASS_CAPA);
+                if (rc)
+                        RETURN(rc);
+
+                if (la->la_nlink >= m->mdd_dt_conf.ddp_max_nlink)
+                        RETURN(-EMLINK);
+        }
+
         RETURN(rc);
 }
 /* src object can be remote that is why we use only fid and type of object */
index 71db429..6fa75fa 100644 (file)
@@ -354,11 +354,17 @@ static inline struct dt_object* mdd_object_child(struct mdd_object *o)
         return container_of0(lu_object_next(mdd2lu_obj(o)),
                              struct dt_object, do_lu);
 }
+
 static inline struct obd_device *mdd2obd_dev(struct mdd_device *mdd)
 {
         return mdd->mdd_obd_dev;
 }
 
+static inline struct mdd_device *mdd_obj2mdd_dev(struct mdd_object *obj)
+{
+        return mdo2mdd(&obj->mod_obj);
+}
+
 static inline const struct lu_fid *mdo2fid(const struct mdd_object *obj)
 {
         return lu_object_fid(&obj->mod_obj.mo_lu);
index 8bc7e2b..231c957 100644 (file)
@@ -567,10 +567,23 @@ check_capabilities:
 int mdd_permission(const struct lu_env *env, struct md_object *obj, int mask)
 {
         struct mdd_object *mdd_obj = md2mdd_obj(obj);
+        int check_link = mask & MAY_LINK;
         int rc;
         ENTRY;
 
+        mask &= ~MAY_LINK;
         rc = mdd_permission_internal_locked(env, mdd_obj, NULL, mask);
+        if (!rc && check_link) {
+                struct lu_attr *la = &mdd_env_info(env)->mti_la;
+                struct mdd_device *m = mdo2mdd(obj);
+
+                rc = mdd_la_get(env, mdd_obj, la, BYPASS_CAPA);
+                if (rc)
+                        RETURN(rc);
+
+                if (la->la_nlink >= m->mdd_dt_conf.ddp_max_nlink)
+                        RETURN(-EMLINK);
+        }
 
         RETURN(rc);
 }
index f5b08fc..753d544 100644 (file)
@@ -615,7 +615,8 @@ static int mdt_reint_rename_tgt(struct mdt_thread_info *info)
         } else /* -ENOENT */ {
                 /* Do permission check for name_insert first */
                 rc = mo_permission(info->mti_env, mdt_object_child(mtgtdir),
-                                   MAY_WRITE);
+                                   MAY_WRITE |
+                                   (S_ISDIR(ma->ma_attr.la_mode) ? MAY_LINK : 0));
                 if (rc)
                         GOTO(out_unlock_tgtdir, rc);