From 517c2e00bea8ca2fa19d9bf0fb91a6115d103c18 Mon Sep 17 00:00:00 2001 From: pravins Date: Thu, 4 Jun 2009 05:59:17 +0000 Subject: [PATCH] b=19151 i=oleg.drokin revalidate root dentry before permission check. --- lustre/llite/dcache.c | 11 ++++++--- lustre/llite/file.c | 57 ++++++++++++++++++++++++++++++++----------- lustre/llite/llite_internal.h | 2 ++ lustre/llite/llite_lib.c | 1 + 4 files changed, 53 insertions(+), 18 deletions(-) diff --git a/lustre/llite/dcache.c b/lustre/llite/dcache.c index d3abbfc..e87a6b8 100644 --- a/lustre/llite/dcache.c +++ b/lustre/llite/dcache.c @@ -388,10 +388,13 @@ int ll_revalidate_it(struct dentry *de, int lookup_flags, if (d_mountpoint(de)) GOTO(out_sa, rc = 1); - /* Root of the lustre tree. Always valid. - * Attributes will be fixed up in ll_inode_revalidate_it */ - if (de == de->d_sb->s_root) - GOTO(out_sa, rc = 1); + /*need to get attributes in case it got changed from other client*/ + if (de == de->d_sb->s_root) { + rc = __ll_inode_revalidate_it(de, it, MDS_INODELOCK_LOOKUP); + if (rc == 0) + rc = 1; + GOTO(out_sa, rc); + } OBD_FAIL_TIMEOUT(OBD_FAIL_MDC_REVALIDATE_PAUSE, 5); ll_frob_intent(&it, &lookup_it); diff --git a/lustre/llite/file.c b/lustre/llite/file.c index 7ddb18c..b16def4 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -3152,12 +3152,13 @@ static int ll_inode_revalidate_fini(struct inode *inode, int rc) { return 0; } -int ll_inode_revalidate_it(struct dentry *dentry, struct lookup_intent *it) +int __ll_inode_revalidate_it(struct dentry *dentry, struct lookup_intent *it, + __u64 ibits) { struct inode *inode = dentry->d_inode; struct ptlrpc_request *req = NULL; struct obd_export *exp; - int rc; + int rc = 0; ENTRY; if (!inode) { @@ -3207,8 +3208,7 @@ int ll_inode_revalidate_it(struct dentry *dentry, struct lookup_intent *it) } ll_lookup_finish_locks(&oit, dentry); - } else if (!ll_have_md_lock(dentry->d_inode, - MDS_INODELOCK_UPDATE|MDS_INODELOCK_LOOKUP)) { + } else if (!ll_have_md_lock(dentry->d_inode, ibits)) { struct ll_sb_info *sbi = ll_i2sbi(dentry->d_inode); struct ll_fid fid; obd_valid valid = OBD_MD_FLGETATTR; @@ -3229,24 +3229,36 @@ int ll_inode_revalidate_it(struct dentry *dentry, struct lookup_intent *it) rc = ll_prep_inode(sbi->ll_osc_exp, &inode, req, REPLY_REC_OFF, NULL); - if (rc) - GOTO(out, rc); } +out: + ptlrpc_req_finished(req); + RETURN(rc); +} + +int ll_inode_revalidate_it(struct dentry *dentry, struct lookup_intent *it) +{ + struct inode *inode = dentry->d_inode; + int rc; + ENTRY; + + rc = __ll_inode_revalidate_it(dentry, it, MDS_INODELOCK_UPDATE | + MDS_INODELOCK_LOOKUP); + /* if object not yet allocated, don't validate size */ - if (ll_i2info(inode)->lli_smd == NULL) { + if (rc == 0 && ll_i2info(inode)->lli_smd == NULL) { LTIME_S(inode->i_atime) = ll_i2info(inode)->lli_lvb.lvb_atime; LTIME_S(inode->i_mtime) = ll_i2info(inode)->lli_lvb.lvb_mtime; LTIME_S(inode->i_ctime) = ll_i2info(inode)->lli_lvb.lvb_ctime; - GOTO(out, rc = 0); + RETURN(0); } /* ll_glimpse_size will prefer locally cached writes if they extend * the file */ - rc = ll_glimpse_size(inode, 0); -out: - ptlrpc_req_finished(req); + if (rc == 0) + rc = ll_glimpse_size(inode, 0); + RETURN(rc); } @@ -3324,11 +3336,28 @@ int ll_inode_permission(struct inode *inode, int mask, struct nameidata *nd) int ll_inode_permission(struct inode *inode, int mask) #endif { - CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p), mask %o\n", - inode->i_ino, inode->i_generation, inode, mask); + int rc = 0; + ENTRY; + + /* as root inode are NOT getting validated in lookup operation, + * need to do it before permission check. */ + + if (inode == inode->i_sb->s_root->d_inode) { + struct lookup_intent it = { .it_op = IT_LOOKUP }; + + rc = __ll_inode_revalidate_it(inode->i_sb->s_root, &it, + MDS_INODELOCK_LOOKUP); + if (rc) + RETURN(rc); + } + + CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p), inode mode %x mask %o\n", + inode->i_ino, inode->i_generation, inode, inode->i_mode, mask); ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_INODE_PERM, 1); - return generic_permission(inode, mask, lustre_check_acl); + rc = generic_permission(inode, mask, lustre_check_acl); + + RETURN(rc); } #else #ifndef HAVE_INODE_PERMISION_2ARGS diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index ddf85ec..933b081 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -766,6 +766,8 @@ int ll_extent_lock(struct ll_file_data *, struct inode *, struct lustre_handle *, int ast_flags); int ll_extent_unlock(struct ll_file_data *, struct inode *, struct lov_stripe_md *, int mode, struct lustre_handle *); +int __ll_inode_revalidate_it(struct dentry *, struct lookup_intent *, __u64 bits); +int ll_revalidate_nd(struct dentry *dentry, struct nameidata *nd); int ll_file_open(struct inode *inode, struct file *file); int ll_file_release(struct inode *inode, struct file *file); int ll_lsm_getattr(struct obd_export *, struct lov_stripe_md *, struct obdo *); diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index 66b2461..475f599 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -244,6 +244,7 @@ static struct dentry_operations ll_d_root_ops = { #ifdef DCACHE_LUSTRE_INVALID .d_compare = ll_dcompare, #endif + .d_revalidate = ll_revalidate_nd, }; static int client_common_fill_super(struct super_block *sb, -- 1.8.3.1