diff --git a/lustre/ChangeLog b/lustre/ChangeLog index 115296e645611baccb434c2804ba57abe0abe1e9..be57870a2509fb227dc2efd94f0e53e1f050c86f 100644 --- a/lustre/ChangeLog +++ b/lustre/ChangeLog @@ -544,6 +544,13 @@ Details : The __iget() symbol export is missing. To avoid the need for off, and we depend on the VM to clean up old inodes. This dependency was during via the fix for bug 12181. +Severity : normal +Frequency : always +Bugzilla : 12848 +Description: sanity.sh fail: test_52b +Details : The ll_inode_to_ext_flags() has a glitch which makes MDS return + incorrect inode's flags to client. + -------------------------------------------------------------------------------- 2007-04-19 Cluster File Systems, Inc. <info@clusterfs.com> diff --git a/lustre/include/lustre/lustre_idl.h b/lustre/include/lustre/lustre_idl.h index d354eb19b115249981cfe7e01005e0d28b40d170..0cdb6a3f64798d06937f966a4385586b2789eb96 100644 --- a/lustre/include/lustre/lustre_idl.h +++ b/lustre/include/lustre/lustre_idl.h @@ -722,13 +722,13 @@ static inline int ll_ext_to_inode_flags(int flags) (flags & ~MDS_BFLAG_EXT_FLAGS); } -/* If MDS_BFLAG_EXT_FLAGS is set it means we requested EXT3_*_FL inode flags - * and we pass these straight through. Otherwise we need to convert from - * S_* flags to their EXT3_*_FL equivalents (see bug 9486). */ -static inline int ll_inode_to_ext_flags(int oflags, int iflags) +/* If keep is set, we do not do anything with iflags, if it is not set, we + * assume that iflags are inode flags and we need to conver those to + * EXT3_*_FL flags (see bug 9486 and 12848) */ +static inline int ll_inode_to_ext_flags(int iflags, int keep) { - return (oflags & MDS_BFLAG_EXT_FLAGS) ? (oflags & ~MDS_BFLAG_EXT_FLAGS): - (((iflags & S_SYNC) ? MDS_SYNC_FL : 0) | + return keep ? (iflags & ~MDS_BFLAG_EXT_FLAGS) : + (((iflags & S_SYNC) ? MDS_SYNC_FL : 0) | ((iflags & S_NOATIME) ? MDS_NOATIME_FL : 0) | ((iflags & S_APPEND) ? MDS_APPEND_FL : 0) | #if defined(S_DIRSYNC) diff --git a/lustre/include/obd_support.h b/lustre/include/obd_support.h index b368b56fc6c8f69dc92da55661dc5948f80cfeb5..5f987d4399fab96ab27ce492f59b7475cd9769df 100644 --- a/lustre/include/obd_support.h +++ b/lustre/include/obd_support.h @@ -194,6 +194,7 @@ extern int obd_race_state; #define OBD_FAIL_MDC_REVALIDATE_PAUSE 0x800 #define OBD_FAIL_MDC_ENQUEUE_PAUSE 0x801 +#define OBD_FAIL_MDC_OLD_EXT_FLAGS 0x802 #define OBD_FAIL_MGS 0x900 #define OBD_FAIL_MGS_ALL_REQUEST_NET 0x901 diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index 4c9411e60c96f6281e055dc45af9a3617c684c70..41a6cece12dc531971b8704a78d84085c6ca5ea4 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -1728,7 +1728,8 @@ int ll_iocontrol(struct inode *inode, struct file *file, /* We want to return EXT3_*_FL flags to the caller via this * ioctl. An older MDS may be sending S_* flags, fix it up. */ - flags = ll_inode_to_ext_flags(body->flags, body->flags); + flags = ll_inode_to_ext_flags(body->flags, + body->flags & MDS_BFLAG_EXT_FLAGS); ptlrpc_req_finished (req); RETURN(put_user(flags, (int *)arg)); diff --git a/lustre/mdc/mdc_lib.c b/lustre/mdc/mdc_lib.c index 7f1a4bca9a5c1dcc68015d5b3c5f572cbc7752ed..8b7c6afa15c7df2230112165b1d5bcb27abe1b0c 100644 --- a/lustre/mdc/mdc_lib.c +++ b/lustre/mdc/mdc_lib.c @@ -302,6 +302,11 @@ void mdc_getattr_pack(struct ptlrpc_request *req, int offset, int valid, b->capability = current->cap_effective; b->valid = valid; b->flags = flags | MDS_BFLAG_EXT_FLAGS; + /* skip MDS_BFLAG_EXT_FLAGS to verify the "client < 1.4.7" case + * refer to bug 12848. + */ + if (OBD_FAIL_CHECK(OBD_FAIL_MDC_OLD_EXT_FLAGS)) + b->flags &= ~MDS_BFLAG_EXT_FLAGS; b->suppgid = data->suppgids[0]; b->fid1 = data->fid1; diff --git a/lustre/mds/mds_lib.c b/lustre/mds/mds_lib.c index 6f9bffbdd96af54f1632a45727ecf2a3bb3c9a02..f24f6ece8a8260bbbc7700ff5f7df68cb7dc6feb 100644 --- a/lustre/mds/mds_lib.c +++ b/lustre/mds/mds_lib.c @@ -82,7 +82,9 @@ void mds_pack_inode2body(struct mds_body *b, struct inode *inode) b->blocks = inode->i_blocks; b->uid = inode->i_uid; b->gid = inode->i_gid; - b->flags = ll_inode_to_ext_flags(b->flags, inode->i_flags); + b->flags = (b->flags & MDS_BFLAG_EXT_FLAGS) | + ll_inode_to_ext_flags(inode->i_flags, + !(b->flags & MDS_BFLAG_EXT_FLAGS)); b->rdev = inode->i_rdev; /* Return the correct link count for orphan inodes */ b->nlink = mds_inode_is_orphan(inode) ? 0 : inode->i_nlink; diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index f3a5d1508dcf6d98ee14a051b1a1561c6f12b5ad..36aef3683d80e0b21a92b73997c2b6768cc12659 100644 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -2188,6 +2188,22 @@ test_52b() { } run_test 52b "immutable flag test (should return errors) =======" +test_52c() { # 12848 simulating client < 1.4.7 + [ -f $DIR/d52c/foo ] && chattr -i $DIR/d52b/foo + mkdir -p $DIR/d52c + touch $DIR/d52c/foo + # skip MDS_BFLAG_EXT_FLAGS in mdc_getattr_pack +#define OBD_FAIL_MDC_OLD_EXT_FLAGS 0x802 + sysctl -w lustre.fail_loc=0x802 + chattr =i $DIR/d52c/foo || error + lsattr $DIR/d52c/foo | egrep -q "^-+i-+ $DIR/d52c/foo" || error + chattr -i $DIR/d52c/foo || error + sysctl -w lustre.fail_loc=0 + + rm -fr $DIR/d52c || error +} +run_test 52c "immutable flag test for client < 1.4.7 =======" + test_53() { [ -z "$MDS" ] && echo "skipping $TESTNAME with remote MDS" && return