From 64408a91c09100bcf29fbdac59507a1e2d985cd6 Mon Sep 17 00:00:00 2001 From: pravins Date: Thu, 7 May 2009 18:57:14 +0000 Subject: [PATCH] b=19151 i=vitaly i=andreas i=ericm i=fanyong re-validate root inode before using inode attribute to perform permission check. --- lustre/llite/dcache.c | 18 +++++++------ lustre/llite/file.c | 61 +++++++++++++++++++++++++++++++------------ lustre/llite/llite_internal.h | 2 ++ lustre/llite/llite_lib.c | 1 + 4 files changed, 58 insertions(+), 24 deletions(-) diff --git a/lustre/llite/dcache.c b/lustre/llite/dcache.c index 985fff7..02aeac5 100644 --- a/lustre/llite/dcache.c +++ b/lustre/llite/dcache.c @@ -393,17 +393,19 @@ int ll_revalidate_it(struct dentry *de, int lookup_flags, GOTO(out_sa, rc); } - exp = ll_i2mdexp(de->d_inode); - /* Never execute intents for mount points. - * Attributes will be fixed up in ll_inode_revalidate_it */ + * 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); + } + 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); + exp = ll_i2mdexp(de->d_inode); OBD_FAIL_TIMEOUT(OBD_FAIL_MDC_REVALIDATE_PAUSE, 5); ll_frob_intent(&it, &lookup_it); @@ -718,7 +720,7 @@ out_sa: } #ifdef HAVE_VFS_INTENT_PATCHES -static int ll_revalidate_nd(struct dentry *dentry, struct nameidata *nd) +int ll_revalidate_nd(struct dentry *dentry, struct nameidata *nd) { int rc; ENTRY; diff --git a/lustre/llite/file.c b/lustre/llite/file.c index 79203b8..17990d8 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -2147,13 +2147,14 @@ 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 ll_sb_info *sbi; struct obd_export *exp; - int rc; + int rc = 0; ENTRY; if (!inode) { @@ -2210,8 +2211,8 @@ 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); obd_valid valid = OBD_MD_FLGETATTR; struct obd_capa *oc; @@ -2236,21 +2237,31 @@ int ll_inode_revalidate_it(struct dentry *dentry, struct lookup_intent *it) } rc = ll_prep_inode(&inode, req, 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) +{ + 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) - GOTO(out, rc = 0); + if (rc == 0 && ll_i2info(dentry->d_inode)->lli_smd == NULL) + RETURN(0); /* cl_glimpse_size will prefer locally cached writes if they extend * the file */ - rc = cl_glimpse_size(inode); - EXIT; -out: - ptlrpc_req_finished(req); - return rc; + + if (rc == 0) + rc = cl_glimpse_size(dentry->d_inode); + + RETURN(rc); } int ll_getattr_it(struct vfsmount *mnt, struct dentry *de, @@ -2323,13 +2334,31 @@ int lustre_check_acl(struct inode *inode, int mask) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)) int ll_inode_permission(struct inode *inode, int mask, struct nameidata *nd) { - 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_GETATTR }; + + 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); + if (ll_i2sbi(inode)->ll_flags & LL_SBI_RMT_CLIENT) return lustre_check_remote_perm(inode, 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 int ll_inode_permission(struct inode *inode, int mask, struct nameidata *nd) diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index 2857837..14428ac 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -634,6 +634,8 @@ extern int ll_inode_revalidate_it(struct dentry *, struct lookup_intent *); extern int ll_have_md_lock(struct inode *inode, __u64 bits); extern ldlm_mode_t ll_take_md_lock(struct inode *inode, __u64 bits, struct lustre_handle *lockh); +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_glimpse_ioctl(struct ll_sb_info *sbi, diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index bda1337..0befcde 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -156,6 +156,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, char *md, char *dt) -- 1.8.3.1