From 20aa053a538959b54773be861e9b82960a53f7d9 Mon Sep 17 00:00:00 2001 From: fanyong Date: Wed, 22 Nov 2006 14:55:39 +0000 Subject: [PATCH] More sanity check for nlink of file. --- lustre/cmm/cmm_object.c | 3 ++- lustre/include/lustre/lustre_idl.h | 3 +++ lustre/mdd/mdd_dir.c | 35 ++++++++++++++++++++++++++++++++++- lustre/mdd/mdd_internal.h | 6 ++++++ lustre/mdd/mdd_permission.c | 13 +++++++++++++ lustre/mdt/mdt_reint.c | 3 ++- 6 files changed, 60 insertions(+), 3 deletions(-) diff --git a/lustre/cmm/cmm_object.c b/lustre/cmm/cmm_object.c index ab6f552..ac0d330 100644 --- a/lustre/cmm/cmm_object.c +++ b/lustre/cmm/cmm_object.c @@ -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); diff --git a/lustre/include/lustre/lustre_idl.h b/lustre/include/lustre/lustre_idl.h index 9015553..9ee7f14 100644 --- a/lustre/include/lustre/lustre_idl.h +++ b/lustre/include/lustre/lustre_idl.h @@ -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 diff --git a/lustre/mdd/mdd_dir.c b/lustre/mdd/mdd_dir.c index 8be0b93..1a586d3 100644 --- a/lustre/mdd/mdd_dir.c +++ b/lustre/mdd/mdd_dir.c @@ -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 */ diff --git a/lustre/mdd/mdd_internal.h b/lustre/mdd/mdd_internal.h index 71db429..6fa75fa 100644 --- a/lustre/mdd/mdd_internal.h +++ b/lustre/mdd/mdd_internal.h @@ -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); diff --git a/lustre/mdd/mdd_permission.c b/lustre/mdd/mdd_permission.c index 8bc7e2b..231c957 100644 --- a/lustre/mdd/mdd_permission.c +++ b/lustre/mdd/mdd_permission.c @@ -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); } diff --git a/lustre/mdt/mdt_reint.c b/lustre/mdt/mdt_reint.c index f5b08fc..753d544 100644 --- a/lustre/mdt/mdt_reint.c +++ b/lustre/mdt/mdt_reint.c @@ -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); -- 1.8.3.1