From 47e6f6abdacd6a3c1fdb320b4c9c331c0f493cce Mon Sep 17 00:00:00 2001 From: James Simmons Date: Thu, 30 Sep 2021 14:57:02 -0400 Subject: [PATCH] LU-12262 llite: harden ll_sbi ll_flags For most file systems mount flags are straight forward but this is not the case for Lustre. We have to consider if the server backend supports a mount option. Additionally its possible to disable or enable a feature using sysfs during run time. Some features can't be managed with a mount option but still can be managed with sysfs or based on what is enabled on the server node. All these states are reported together in the debugfs file sbi_flags. The mount specific options are reported in the super block show_option ll_show_option(). With all this complexity it is easy for it to get out of sync and report incorrect things. We consolidate this handling by moving to using match_table_t that is used by various Linux file system to parse options. LL_SBI_FLAGS is replaced by our match_table_t, ll_sbi_flags_name, that can be used for mount options as well as reporting the sbi_flags in debugfs. We take advantage of the fact that mount option parse will stop at the first NULL in ll_sbi_flags_name and after that NULL list the other features flags that are managed with other methods besides mount options. The next change is the move of ll_flags to a bitmap which gives us two advantages. The first is that we can support more than 32 flags in the future. Second is no need to use bit shifting math since we can use th enum LL_SBI_* values directly with clear_bit() / set_bit() / test_bit(). Allow these changes should miminize future problems with keeping all these states in sync. Change-Id: Ia4f08cdde54c0fd11440dcf6b60b5fcb8bfb4d63 Signed-off-by: James Simmons Reviewed-on: https://review.whamcloud.com/44541 Reviewed-by: Andreas Dilger Reviewed-by: Neil Brown Tested-by: jenkins Tested-by: Maloo Reviewed-by: Oleg Drokin --- libcfs/autoconf/lustre-libcfs.m4 | 20 ++ libcfs/include/libcfs/linux/linux-misc.h | 4 + libcfs/libcfs/linux/linux-prim.c | 53 ++++ lustre/llite/crypto.c | 15 +- lustre/llite/dir.c | 24 +- lustre/llite/file.c | 11 +- lustre/llite/llite_foreign_symlink.c | 12 +- lustre/llite/llite_internal.h | 131 +++------ lustre/llite/llite_lib.c | 490 ++++++++++++++++--------------- lustre/llite/lproc_llite.c | 72 ++--- lustre/llite/namei.c | 14 +- lustre/llite/statahead.c | 3 +- lustre/llite/xattr.c | 8 +- 13 files changed, 445 insertions(+), 412 deletions(-) diff --git a/libcfs/autoconf/lustre-libcfs.m4 b/libcfs/autoconf/lustre-libcfs.m4 index b425654..07c4de9 100644 --- a/libcfs/autoconf/lustre-libcfs.m4 +++ b/libcfs/autoconf/lustre-libcfs.m4 @@ -197,6 +197,24 @@ shrinker_count_objects, [ ]) # LIBCFS_SHRINKER_COUNT # +# Kernel version 3.13 commit aace05097a0fd467230e39acb148be0fdaa90068 +# add match_wildcard() function. +# +AC_DEFUN([LIBCFS_MATCH_WILDCARD],[ +LB_CHECK_COMPILE([does function 'match_wildcard' exist], +match_wildcard, [ + #include +],[ + bool match; + + match = match_wildcard(NULL, NULL); +],[ + AC_DEFINE(HAVE_MATCH_WILDCARD, 1, + [match_wildcard() is available]) +]) +]) # LIBCFS_MATCH_WILDCARD + +# # LIBCFS_HAVE_MAPPING_AS_EXITING_FLAG # # v3.14-7405-g91b0abe36a7b added AS_EXITING flag with @@ -1698,6 +1716,8 @@ LIBCFS_KTIME_AFTER LIBCFS_KTIME_BEFORE LIBCFS_KTIME_COMPARE LIBCFS_SHRINKER_COUNT +# 3.13 +LIBCFS_MATCH_WILDCARD # 3.15 LIBCFS_HAVE_MAPPING_AS_EXITING_FLAG LIBCFS_IOV_ITER_HAS_TYPE diff --git a/libcfs/include/libcfs/linux/linux-misc.h b/libcfs/include/libcfs/linux/linux-misc.h index 242105b..b9963e4 100644 --- a/libcfs/include/libcfs/linux/linux-misc.h +++ b/libcfs/include/libcfs/linux/linux-misc.h @@ -97,6 +97,10 @@ int cfs_apply_workqueue_attrs(struct workqueue_struct *wq, int kstrtobool_from_user(const char __user *s, size_t count, bool *res); #endif /* HAVE_KSTRTOBOOL_FROM_USER */ +#ifndef HAVE_MATCH_WILDCARD +bool match_wildcard(const char *pattern, const char *str); +#endif /* !HAVE_MATCH_WILDCARD */ + #ifndef HAVE_KREF_READ static inline int kref_read(const struct kref *kref) { diff --git a/libcfs/libcfs/linux/linux-prim.c b/libcfs/libcfs/linux/linux-prim.c index 1bdab05..5f2f6ae 100644 --- a/libcfs/libcfs/linux/linux-prim.c +++ b/libcfs/libcfs/linux/linux-prim.c @@ -187,6 +187,59 @@ struct kobject *kset_find_obj(struct kset *kset, const char *name) EXPORT_SYMBOL_GPL(kset_find_obj); #endif +#ifndef HAVE_MATCH_WILDCARD +/** + * match_wildcard: - parse if a string matches given wildcard pattern + * @pattern: wildcard pattern + * @str: the string to be parsed + * + * Description: Parse the string @str to check if matches wildcard + * pattern @pattern. The pattern may contain two type wildcardes: + * '*' - matches zero or more characters + * '?' - matches one character + * If it's matched, return true, else return false. + */ +bool match_wildcard(const char *pattern, const char *str) +{ + const char *s = str; + const char *p = pattern; + bool star = false; + + while (*s) { + switch (*p) { + case '?': + s++; + p++; + break; + case '*': + star = true; + str = s; + if (!*++p) + return true; + pattern = p; + break; + default: + if (*s == *p) { + s++; + p++; + } else { + if (!star) + return false; + str++; + s = str; + p = pattern; + } + break; + } + } + + if (*p == '*') + ++p; + return !*p; +} +EXPORT_SYMBOL(match_wildcard); +#endif /* !HAVE_MATCH_WILDCARD */ + #ifndef HAVE_KSTRTOBOOL_FROM_USER int kstrtobool_from_user(const char __user *s, size_t count, bool *res) { diff --git a/lustre/llite/crypto.c b/lustre/llite/crypto.c index e8d87d6..7a073c9 100644 --- a/lustre/llite/crypto.c +++ b/lustre/llite/crypto.c @@ -139,7 +139,7 @@ void llcrypt_free_ctx(void *encctx, __u32 size) bool ll_sbi_has_test_dummy_encryption(struct ll_sb_info *sbi) { - return unlikely(sbi->ll_flags & LL_SBI_TEST_DUMMY_ENCRYPTION); + return unlikely(test_bit(LL_SBI_TEST_DUMMY_ENCRYPTION, sbi->ll_flags)); } static bool ll_dummy_context(struct inode *inode) @@ -151,16 +151,17 @@ static bool ll_dummy_context(struct inode *inode) bool ll_sbi_has_encrypt(struct ll_sb_info *sbi) { - return sbi->ll_flags & LL_SBI_ENCRYPT; + return test_bit(LL_SBI_ENCRYPT, sbi->ll_flags); } void ll_sbi_set_encrypt(struct ll_sb_info *sbi, bool set) { - if (set) - sbi->ll_flags |= LL_SBI_ENCRYPT; - else - sbi->ll_flags &= - ~(LL_SBI_ENCRYPT | LL_SBI_TEST_DUMMY_ENCRYPTION); + if (set) { + set_bit(LL_SBI_ENCRYPT, sbi->ll_flags); + } else { + clear_bit(LL_SBI_ENCRYPT, sbi->ll_flags); + clear_bit(LL_SBI_TEST_DUMMY_ENCRYPTION, sbi->ll_flags); + } } static bool ll_empty_dir(struct inode *inode) diff --git a/lustre/llite/dir.c b/lustre/llite/dir.c index 9d81d58..0a2725c 100644 --- a/lustre/llite/dir.c +++ b/lustre/llite/dir.c @@ -190,7 +190,7 @@ int ll_dir_read(struct inode *inode, __u64 *ppos, struct md_op_data *op_data, struct ll_sb_info *sbi = ll_i2sbi(inode); __u64 pos = *ppos; bool is_api32 = ll_need_32bit_api(sbi); - bool is_hash64 = sbi->ll_flags & LL_SBI_64BIT_HASH; + bool is_hash64 = test_bit(LL_SBI_64BIT_HASH, sbi->ll_flags); struct page *page; bool done = false; struct llcrypt_str lltr = LLTR_INIT(NULL, 0); @@ -320,7 +320,7 @@ static int ll_readdir(struct file *filp, void *cookie, filldir_t filldir) struct inode *inode = file_inode(filp); struct ll_file_data *lfd = filp->private_data; struct ll_sb_info *sbi = ll_i2sbi(inode); - int hash64 = sbi->ll_flags & LL_SBI_64BIT_HASH; + bool hash64 = test_bit(LL_SBI_64BIT_HASH, sbi->ll_flags); int api32 = ll_need_32bit_api(sbi); struct md_op_data *op_data; struct lu_fid pfid = { 0 }; @@ -524,7 +524,7 @@ static int ll_dir_setdirstripe(struct dentry *dparent, struct lmv_user_md *lump, encrypt = true; } - if (sbi->ll_flags & LL_SBI_FILE_SECCTX) { + if (test_bit(LL_SBI_FILE_SECCTX, sbi->ll_flags)) { /* selinux_dentry_init_security() uses dentry->d_parent and name * to determine the security context for the file. So our fake * dentry should be real enough for this purpose. */ @@ -561,7 +561,7 @@ static int ll_dir_setdirstripe(struct dentry *dparent, struct lmv_user_md *lump, dentry.d_inode = inode; - if (sbi->ll_flags & LL_SBI_FILE_SECCTX) { + if (test_bit(LL_SBI_FILE_SECCTX, sbi->ll_flags)) { /* no need to protect selinux_inode_setsecurity() by * inode_lock. Taking it would lead to a client deadlock * LU-13617 @@ -1315,6 +1315,7 @@ out: int ll_rmfid(struct file *file, void __user *arg) { const struct fid_array __user *ufa = arg; + struct inode *inode = file_inode(file); struct fid_array *lfa = NULL; size_t size; unsigned nr; @@ -1322,7 +1323,7 @@ int ll_rmfid(struct file *file, void __user *arg) ENTRY; if (!capable(CAP_DAC_READ_SEARCH) && - !(ll_i2sbi(file_inode(file))->ll_flags & LL_SBI_USER_FID2PATH)) + !test_bit(LL_SBI_USER_FID2PATH, ll_i2sbi(inode)->ll_flags)) RETURN(-EPERM); /* Only need to get the buflen */ if (get_user(nr, &ufa->fa_nr)) @@ -1766,6 +1767,7 @@ out_rmdir: __u32 __user *lmmsizep = NULL; struct lu_fid __user *fidp = NULL; int lmmsize; + bool api32; if (cmd == IOC_MDC_GETFILEINFO_V1 || cmd == IOC_MDC_GETFILEINFO_V2 || @@ -1833,6 +1835,7 @@ out_rmdir: GOTO(out_req, rc = -EFAULT); rc = -EOVERFLOW; } + api32 = test_bit(LL_SBI_32BIT_API, sbi->ll_flags); if (cmd == IOC_MDC_GETFILEINFO_V1 || cmd == LL_IOC_MDC_GETINFO_V1) { @@ -1851,8 +1854,7 @@ out_rmdir: st.st_mtime = body->mbo_mtime; st.st_ctime = body->mbo_ctime; st.st_ino = cl_fid_build_ino(&body->mbo_fid1, - sbi->ll_flags & - LL_SBI_32BIT_API); + api32); if (copy_to_user(statp, &st, sizeof(st))) GOTO(out_req, rc = -EFAULT); @@ -1867,8 +1869,7 @@ out_rmdir: stx.stx_gid = body->mbo_gid; stx.stx_mode = body->mbo_mode; stx.stx_ino = cl_fid_build_ino(&body->mbo_fid1, - sbi->ll_flags & - LL_SBI_32BIT_API); + api32); stx.stx_size = body->mbo_size; stx.stx_blocks = body->mbo_blocks; stx.stx_atime.tv_sec = body->mbo_atime; @@ -2284,10 +2285,13 @@ static loff_t ll_dir_seek(struct file *file, loff_t offset, int origin) ((api32 && offset <= LL_DIR_END_OFF_32BIT) || (!api32 && offset <= LL_DIR_END_OFF))) { if (offset != file->f_pos) { + bool hash64; + + hash64 = test_bit(LL_SBI_64BIT_HASH, sbi->ll_flags); if ((api32 && offset == LL_DIR_END_OFF_32BIT) || (!api32 && offset == LL_DIR_END_OFF)) fd->lfd_pos = MDS_DIR_END_OFF; - else if (api32 && sbi->ll_flags & LL_SBI_64BIT_HASH) + else if (api32 && hash64) fd->lfd_pos = offset << 32; else fd->lfd_pos = offset; diff --git a/lustre/llite/file.c b/lustre/llite/file.c index 98f5de3..474c2e5 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -2752,7 +2752,7 @@ int ll_fid2path(struct inode *inode, void __user *arg) ENTRY; if (!capable(CAP_DAC_READ_SEARCH) && - !(ll_i2sbi(inode)->ll_flags & LL_SBI_USER_FID2PATH)) + !test_bit(LL_SBI_USER_FID2PATH, ll_i2sbi(inode)->ll_flags)) RETURN(-EPERM); /* Only need to get the buflen */ @@ -5507,7 +5507,7 @@ int ll_inode_permission(struct inode *inode, int mask) squash = &sbi->ll_squash; if (unlikely(squash->rsi_uid != 0 && uid_eq(current_fsuid(), GLOBAL_ROOT_UID) && - !(sbi->ll_flags & LL_SBI_NOROOTSQUASH))) { + !test_bit(LL_SBI_NOROOTSQUASH, sbi->ll_flags))) { squash_id = true; } if (squash_id) { @@ -5657,9 +5657,9 @@ const struct file_operations *ll_select_file_operations(struct ll_sb_info *sbi) { const struct file_operations *fops = &ll_file_operations_noflock; - if (sbi->ll_flags & LL_SBI_FLOCK) + if (test_bit(LL_SBI_FLOCK, sbi->ll_flags)) fops = &ll_file_operations_flock; - else if (sbi->ll_flags & LL_SBI_LOCALFLOCK) + else if (test_bit(LL_SBI_LOCALFLOCK, sbi->ll_flags)) fops = &ll_file_operations; return fops; @@ -5947,7 +5947,8 @@ int ll_layout_refresh(struct inode *inode, __u32 *gen) ENTRY; *gen = ll_layout_version_get(lli); - if (!(sbi->ll_flags & LL_SBI_LAYOUT_LOCK) || *gen != CL_LAYOUT_GEN_NONE) + if (!test_bit(LL_SBI_LAYOUT_LOCK, sbi->ll_flags) || + *gen != CL_LAYOUT_GEN_NONE) RETURN(0); /* sanity checks */ diff --git a/lustre/llite/llite_foreign_symlink.c b/lustre/llite/llite_foreign_symlink.c index c36f363..d401fa0 100644 --- a/lustre/llite/llite_foreign_symlink.c +++ b/lustre/llite/llite_foreign_symlink.c @@ -203,7 +203,7 @@ static int ll_foreign_symlink_parse(struct ll_sb_info *sbi, * of foreign LOV is relative path of faked symlink destination, * to be completed by prefix */ - if (!(sbi->ll_flags & LL_SBI_FOREIGN_SYMLINK_UPCALL)) + if (!test_bit(LL_SBI_FOREIGN_SYMLINK_UPCALL, sbi->ll_flags)) rc = ll_foreign_symlink_default_parse(sbi, inode, lfm, destname); else /* upcall is available */ @@ -448,7 +448,7 @@ ssize_t foreign_symlink_enable_show(struct kobject *kobj, ll_kset.kobj); return snprintf(buf, PAGE_SIZE, "%d\n", - !!(sbi->ll_flags & LL_SBI_FOREIGN_SYMLINK)); + test_bit(LL_SBI_FOREIGN_SYMLINK, sbi->ll_flags)); } /* @@ -475,9 +475,9 @@ ssize_t foreign_symlink_enable_store(struct kobject *kobj, return rc; if (val) - sbi->ll_flags |= LL_SBI_FOREIGN_SYMLINK; + set_bit(LL_SBI_FOREIGN_SYMLINK, sbi->ll_flags); else - sbi->ll_flags &= ~LL_SBI_FOREIGN_SYMLINK; + clear_bit(LL_SBI_FOREIGN_SYMLINK, sbi->ll_flags); return count; } @@ -609,7 +609,7 @@ ssize_t foreign_symlink_upcall_store(struct kobject *kobj, * order, we may end up using the format provided by a different * upcall than the one set in ll_foreign_symlink_upcall */ - sbi->ll_flags &= ~LL_SBI_FOREIGN_SYMLINK_UPCALL; + clear_bit(LL_SBI_FOREIGN_SYMLINK_UPCALL, sbi->ll_flags); up_write(&sbi->ll_foreign_symlink_sem); if (strcmp(new, "none")) { @@ -752,7 +752,7 @@ ssize_t foreign_symlink_upcall_info_store(struct kobject *kobj, old_nb_items = sbi->ll_foreign_symlink_upcall_nb_items; sbi->ll_foreign_symlink_upcall_items = new_items; sbi->ll_foreign_symlink_upcall_nb_items = nb_items; - sbi->ll_flags |= LL_SBI_FOREIGN_SYMLINK_UPCALL; + set_bit(LL_SBI_FOREIGN_SYMLINK_UPCALL, sbi->ll_flags); up_write(&sbi->ll_foreign_symlink_sem); /* free old_items */ diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index 1097608..4bbe0c6 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -611,75 +612,39 @@ enum stats_track_type { }; /* flags for sbi->ll_flags */ -#define LL_SBI_NOLCK 0x01 /* DLM locking disabled (directio-only) */ -#define LL_SBI_CHECKSUM 0x02 /* checksum each page as it's written */ -#define LL_SBI_FLOCK 0x04 -#define LL_SBI_USER_XATTR 0x08 /* support user xattr */ -#define LL_SBI_ACL 0x10 /* support ACL */ -/* LL_SBI_RMT_CLIENT 0x40 remote client */ -#define LL_SBI_MDS_CAPA 0x80 /* support mds capa, obsolete */ -#define LL_SBI_OSS_CAPA 0x100 /* support oss capa, obsolete */ -#define LL_SBI_LOCALFLOCK 0x200 /* Local flocks support by kernel */ -#define LL_SBI_LRU_RESIZE 0x400 /* lru resize support */ -#define LL_SBI_LAZYSTATFS 0x800 /* lazystatfs mount option */ -/* LL_SBI_SOM_PREVIEW 0x1000 SOM preview mount option, obsolete */ -#define LL_SBI_32BIT_API 0x2000 /* generate 32 bit inodes. */ -#define LL_SBI_64BIT_HASH 0x4000 /* support 64-bits dir hash/offset */ -#define LL_SBI_AGL_ENABLED 0x8000 /* enable agl */ -#define LL_SBI_VERBOSE 0x10000 /* verbose mount/umount */ -#define LL_SBI_LAYOUT_LOCK 0x20000 /* layout lock support */ -#define LL_SBI_USER_FID2PATH 0x40000 /* allow fid2path by unprivileged users */ -#define LL_SBI_XATTR_CACHE 0x80000 /* support for xattr cache */ -#define LL_SBI_NOROOTSQUASH 0x100000 /* do not apply root squash */ -#define LL_SBI_ALWAYS_PING 0x200000 /* always ping even if server - * suppress_pings */ -#define LL_SBI_FAST_READ 0x400000 /* fast read support */ -#define LL_SBI_FILE_SECCTX 0x800000 /* set file security context at create */ -/* LL_SBI_PIO 0x1000000 parallel IO support, introduced in - 2.10, abandoned */ -#define LL_SBI_TINY_WRITE 0x2000000 /* tiny write support */ -#define LL_SBI_FILE_HEAT 0x4000000 /* file heat support */ -#define LL_SBI_TEST_DUMMY_ENCRYPTION 0x8000000 /* test dummy encryption */ -#define LL_SBI_ENCRYPT 0x10000000 /* client side encryption */ -#define LL_SBI_FOREIGN_SYMLINK 0x20000000 /* foreign fake-symlink support */ -/* foreign fake-symlink upcall registered */ -#define LL_SBI_FOREIGN_SYMLINK_UPCALL 0x40000000 -#define LL_SBI_PARALLEL_DIO 0x80000000 /* parallel (async) submission of - RPCs for DIO */ -#define LL_SBI_FLAGS { \ - "nolck", \ - "checksum", \ - "flock", \ - "user_xattr", \ - "acl", \ - "???", \ - "???", \ - "mds_capa", \ - "oss_capa", \ - "flock", \ - "lru_resize", \ - "lazy_statfs", \ - "som", \ - "32bit_api", \ - "64bit_hash", \ - "agl", \ - "verbose", \ - "layout", \ - "user_fid2path",\ - "xattr_cache", \ - "norootsquash", \ - "always_ping", \ - "fast_read", \ - "file_secctx", \ - "pio", \ - "tiny_write", \ - "file_heat", \ - "test_dummy_encryption", \ - "noencrypt", \ - "foreign_symlink", \ - "foreign_symlink_upcall", \ - "parallel_dio", \ -} +enum ll_sbi_flags { + LL_SBI_NOLCK, /* DLM locking disabled directio-only */ + LL_SBI_CHECKSUM, /* checksum each page as it's written */ + LL_SBI_LOCALFLOCK, /* local flocks instead of fs-wide */ + LL_SBI_FLOCK, /* flock enabled */ + LL_SBI_USER_XATTR, /* support user xattr */ + LL_SBI_LRU_RESIZE, /* lru resize support */ + LL_SBI_LAZYSTATFS, /* lazystatfs mount option */ + LL_SBI_32BIT_API, /* generate 32 bit inodes. */ + LL_SBI_USER_FID2PATH, /* fid2path by unprivileged users */ + LL_SBI_VERBOSE, /* verbose mount/umount */ + LL_SBI_ALWAYS_PING, /* ping even if server suppress_pings */ + LL_SBI_TEST_DUMMY_ENCRYPTION, /* test dummy encryption */ + LL_SBI_ENCRYPT, /* client side encryption */ + LL_SBI_FOREIGN_SYMLINK, /* foreign fake-symlink support */ + LL_SBI_FOREIGN_SYMLINK_UPCALL, /* foreign fake-symlink upcall set */ + LL_SBI_NUM_MOUNT_OPT, + + LL_SBI_ACL, /* support ACL */ + LL_SBI_AGL_ENABLED, /* enable agl */ + LL_SBI_64BIT_HASH, /* support 64-bits dir hash/offset */ + LL_SBI_LAYOUT_LOCK, /* layout lock support */ + LL_SBI_XATTR_CACHE, /* support for xattr cache */ + LL_SBI_NOROOTSQUASH, /* do not apply root squash */ + LL_SBI_FAST_READ, /* fast read support */ + LL_SBI_FILE_SECCTX, /* file security context at create */ + LL_SBI_TINY_WRITE, /* tiny write support */ + LL_SBI_FILE_HEAT, /* file heat support */ + LL_SBI_PARALLEL_DIO, /* parallel (async) O_DIRECT RPCs */ + LL_SBI_NUM_FLAGS +}; + +int ll_sbi_flags_seq_show(struct seq_file *m, void *v); /* This is embedded into llite super-blocks to keep track of connect * flags (capabilities) supported by all imports given mount is @@ -708,13 +673,13 @@ struct ll_sb_info { struct dentry *ll_debugfs_entry; struct lu_fid ll_root_fid; /* root object fid */ - int ll_flags; - unsigned int ll_xattr_cache_enabled:1, - ll_xattr_cache_set:1, /* already set to 0/1 */ - ll_client_common_fill_super_succeeded:1, - ll_checksum_set:1; + DECLARE_BITMAP(ll_flags, LL_SBI_NUM_FLAGS); /* enum ll_sbi_flags */ + unsigned int ll_xattr_cache_enabled:1, + ll_xattr_cache_set:1, /* already set to 0/1 */ + ll_client_common_fill_super_succeeded:1, + ll_checksum_set:1; - struct lustre_client_ocd ll_lco; + struct lustre_client_ocd ll_lco; struct lprocfs_stats *ll_stats; /* lprocfs stats counter */ @@ -957,7 +922,7 @@ static inline int ll_need_32bit_api(struct ll_sb_info *sbi) #if BITS_PER_LONG == 32 return 1; #elif defined(CONFIG_COMPAT) - if (unlikely(sbi->ll_flags & LL_SBI_32BIT_API)) + if (unlikely(test_bit(LL_SBI_32BIT_API, sbi->ll_flags))) return true; # ifdef CONFIG_X86_X32 @@ -971,33 +936,33 @@ static inline int ll_need_32bit_api(struct ll_sb_info *sbi) return unlikely(in_compat_syscall()); #else - return unlikely(sbi->ll_flags & LL_SBI_32BIT_API); + return unlikely(test_bit(LL_SBI_32BIT_API, sbi->ll_flags)); #endif } static inline bool ll_sbi_has_fast_read(struct ll_sb_info *sbi) { - return !!(sbi->ll_flags & LL_SBI_FAST_READ); + return test_bit(LL_SBI_FAST_READ, sbi->ll_flags); } static inline bool ll_sbi_has_tiny_write(struct ll_sb_info *sbi) { - return !!(sbi->ll_flags & LL_SBI_TINY_WRITE); + return test_bit(LL_SBI_TINY_WRITE, sbi->ll_flags); } static inline bool ll_sbi_has_file_heat(struct ll_sb_info *sbi) { - return !!(sbi->ll_flags & LL_SBI_FILE_HEAT); + return test_bit(LL_SBI_FILE_HEAT, sbi->ll_flags); } static inline bool ll_sbi_has_foreign_symlink(struct ll_sb_info *sbi) { - return !!(sbi->ll_flags & LL_SBI_FOREIGN_SYMLINK); + return test_bit(LL_SBI_FOREIGN_SYMLINK, sbi->ll_flags); } static inline bool ll_sbi_has_parallel_dio(struct ll_sb_info *sbi) { - return !!(sbi->ll_flags & LL_SBI_PARALLEL_DIO); + return test_bit(LL_SBI_PARALLEL_DIO, sbi->ll_flags); } void ll_ras_enter(struct file *f, loff_t pos, size_t count); @@ -1609,7 +1574,7 @@ static inline int ll_file_nolock(const struct file *file) LASSERT(fd != NULL); return ((fd->fd_flags & LL_FILE_IGNORE_LOCK) || - (ll_i2sbi(inode)->ll_flags & LL_SBI_NOLCK)); + test_bit(LL_SBI_NOLCK, ll_i2sbi(inode)->ll_flags)); } static inline void ll_set_lock_data(struct obd_export *exp, struct inode *inode, diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index 2df83df..0fb7d9a 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -52,6 +52,7 @@ #ifndef HAVE_CPUS_READ_LOCK #include #endif +#include #include #ifdef HAVE_UAPI_LINUX_MOUNT_H #include @@ -157,18 +158,18 @@ static struct ll_sb_info *ll_init_sbi(void) sbi->ll_ra_info.ra_max_read_ahead_whole_pages = -1; atomic_set(&sbi->ll_ra_info.ra_async_inflight, 0); - sbi->ll_flags |= LL_SBI_VERBOSE; + set_bit(LL_SBI_VERBOSE, sbi->ll_flags); #ifdef ENABLE_CHECKSUM - sbi->ll_flags |= LL_SBI_CHECKSUM; + set_bit(LL_SBI_CHECKSUM, sbi->ll_flags); #endif #ifdef ENABLE_FLOCK - sbi->ll_flags |= LL_SBI_FLOCK; + set_bit(LL_SBI_FLOCK, sbi->ll_flags); #endif #ifdef HAVE_LRU_RESIZE_SUPPORT - sbi->ll_flags |= LL_SBI_LRU_RESIZE; + set_bit(LL_SBI_LRU_RESIZE, sbi->ll_flags); #endif - sbi->ll_flags |= LL_SBI_LAZYSTATFS; + set_bit(LL_SBI_LAZYSTATFS, sbi->ll_flags); for (i = 0; i <= LL_PROCESS_HIST_MAX; i++) { spin_lock_init(&sbi->ll_rw_extents_info.pp_extents[i]. @@ -184,10 +185,10 @@ static struct ll_sb_info *ll_init_sbi(void) atomic_set(&sbi->ll_sa_wrong, 0); atomic_set(&sbi->ll_sa_running, 0); atomic_set(&sbi->ll_agl_total, 0); - sbi->ll_flags |= LL_SBI_AGL_ENABLED; - sbi->ll_flags |= LL_SBI_FAST_READ; - sbi->ll_flags |= LL_SBI_TINY_WRITE; - sbi->ll_flags |= LL_SBI_PARALLEL_DIO; + set_bit(LL_SBI_AGL_ENABLED, sbi->ll_flags); + set_bit(LL_SBI_FAST_READ, sbi->ll_flags); + set_bit(LL_SBI_TINY_WRITE, sbi->ll_flags); + set_bit(LL_SBI_PARALLEL_DIO, sbi->ll_flags); ll_sbi_set_encrypt(sbi, true); /* root squash */ @@ -278,6 +279,7 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt) struct lustre_md lmd; u64 valid; int size, err, checksum; + bool api32; ENTRY; sbi->ll_md_obd = class_name2obd(md); @@ -341,7 +343,7 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt) OBD_CONNECT2_ATOMIC_OPEN_LOCK; #ifdef HAVE_LRU_RESIZE_SUPPORT - if (sbi->ll_flags & LL_SBI_LRU_RESIZE) + if (test_bit(LL_SBI_LRU_RESIZE, sbi->ll_flags)) data->ocd_connect_flags |= OBD_CONNECT_LRU_RESIZE; #endif data->ocd_connect_flags |= OBD_CONNECT_ACL_FLAGS; @@ -358,7 +360,7 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt) if (sb->s_flags & SB_RDONLY) data->ocd_connect_flags |= OBD_CONNECT_RDONLY; - if (sbi->ll_flags & LL_SBI_USER_XATTR) + if (test_bit(LL_SBI_USER_XATTR, sbi->ll_flags)) data->ocd_connect_flags |= OBD_CONNECT_XATTR; #ifdef SB_NOSEC @@ -370,7 +372,7 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt) sbi->ll_fop = ll_select_file_operations(sbi); /* always ping even if server suppress_pings */ - if (sbi->ll_flags & LL_SBI_ALWAYS_PING) + if (test_bit(LL_SBI_ALWAYS_PING, sbi->ll_flags)) data->ocd_connect_flags &= ~OBD_CONNECT_PINGLESS; obd_connect_set_secctx(data); @@ -456,34 +458,34 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt) sbi->ll_namelen = osfs->os_namelen; sbi->ll_mnt.mnt = current->fs->root.mnt; - if ((sbi->ll_flags & LL_SBI_USER_XATTR) && + if (test_bit(LL_SBI_USER_XATTR, sbi->ll_flags) && !(data->ocd_connect_flags & OBD_CONNECT_XATTR)) { LCONSOLE_INFO("Disabling user_xattr feature because " "it is not supported on the server\n"); - sbi->ll_flags &= ~LL_SBI_USER_XATTR; + clear_bit(LL_SBI_USER_XATTR, sbi->ll_flags); } if (data->ocd_connect_flags & OBD_CONNECT_ACL) { #ifdef SB_POSIXACL sb->s_flags |= SB_POSIXACL; #endif - sbi->ll_flags |= LL_SBI_ACL; + set_bit(LL_SBI_ACL, sbi->ll_flags); } else { LCONSOLE_INFO("client wants to enable acl, but mdt not!\n"); #ifdef SB_POSIXACL sb->s_flags &= ~SB_POSIXACL; #endif - sbi->ll_flags &= ~LL_SBI_ACL; + clear_bit(LL_SBI_ACL, sbi->ll_flags); } if (data->ocd_connect_flags & OBD_CONNECT_64BITHASH) - sbi->ll_flags |= LL_SBI_64BIT_HASH; + set_bit(LL_SBI_64BIT_HASH, sbi->ll_flags); if (data->ocd_connect_flags & OBD_CONNECT_LAYOUTLOCK) - sbi->ll_flags |= LL_SBI_LAYOUT_LOCK; + set_bit(LL_SBI_LAYOUT_LOCK, sbi->ll_flags); if (obd_connect_has_secctx(data)) - sbi->ll_flags |= LL_SBI_FILE_SECCTX; + set_bit(LL_SBI_FILE_SECCTX, sbi->ll_flags); if (ll_sbi_has_encrypt(sbi) && !obd_connect_has_enc(data)) { if (ll_sbi_has_test_dummy_encryption(sbi)) @@ -500,7 +502,7 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt) } else if (!sbi->ll_xattr_cache_set) { /* If xattr_cache is already set (no matter 0 or 1) * during processing llog, it won't be enabled here. */ - sbi->ll_flags |= LL_SBI_XATTR_CACHE; + set_bit(LL_SBI_XATTR_CACHE, sbi->ll_flags); sbi->ll_xattr_cache_enabled = 1; } } @@ -552,7 +554,7 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt) data->ocd_connect_flags |= OBD_CONNECT_LRU_RESIZE; #endif /* always ping even if server suppress_pings */ - if (sbi->ll_flags & LL_SBI_ALWAYS_PING) + if (test_bit(LL_SBI_ALWAYS_PING, sbi->ll_flags)) data->ocd_connect_flags &= ~OBD_CONNECT_PINGLESS; if (ll_sbi_has_encrypt(sbi)) @@ -645,7 +647,7 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt) /* make root inode * XXX: move this to after cbd setup? */ valid = OBD_MD_FLGETATTR | OBD_MD_FLBLOCKS | OBD_MD_FLMODEASIZE; - if (sbi->ll_flags & LL_SBI_ACL) + if (test_bit(LL_SBI_ACL, sbi->ll_flags)) valid |= OBD_MD_FLACL; OBD_ALLOC_PTR(op_data); @@ -674,9 +676,8 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt) } LASSERT(fid_is_sane(&sbi->ll_root_fid)); - root = ll_iget(sb, cl_fid_build_ino(&sbi->ll_root_fid, - sbi->ll_flags & LL_SBI_32BIT_API), - &lmd); + api32 = test_bit(LL_SBI_32BIT_API, sbi->ll_flags); + root = ll_iget(sb, cl_fid_build_ino(&sbi->ll_root_fid, api32), &lmd); md_free_lustre_md(sbi->ll_md_exp, &lmd); ptlrpc_req_finished(request); @@ -689,7 +690,7 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt) GOTO(out_root, err); } - checksum = sbi->ll_flags & LL_SBI_CHECKSUM; + checksum = test_bit(LL_SBI_CHECKSUM, sbi->ll_flags); if (sbi->ll_checksum_set) { err = obd_set_info_async(NULL, sbi->ll_dt_exp, sizeof(KEY_CHECKSUM), KEY_CHECKSUM, @@ -892,183 +893,196 @@ void ll_kill_super(struct super_block *sb) EXIT; } -static inline int ll_set_opt(const char *opt, char *data, int fl) +/* Since we use this table for ll_sbi_flags_seq_show make + * sure what you want displayed for a specific token that + * is listed more than once below be listed first. For + * example we want "checksum" displayed, not "nochecksum" + * for the sbi_flags. + */ +static const match_table_t ll_sbi_flags_name = { + {LL_SBI_NOLCK, "nolock"}, + {LL_SBI_CHECKSUM, "checksum"}, + {LL_SBI_CHECKSUM, "nochecksum"}, + {LL_SBI_LOCALFLOCK, "localflock"}, + {LL_SBI_FLOCK, "flock"}, + {LL_SBI_FLOCK, "noflock"}, + {LL_SBI_USER_XATTR, "user_xattr"}, + {LL_SBI_USER_XATTR, "nouser_xattr"}, + {LL_SBI_LRU_RESIZE, "lruresize"}, + {LL_SBI_LRU_RESIZE, "nolruresize"}, + {LL_SBI_LAZYSTATFS, "lazystatfs"}, + {LL_SBI_LAZYSTATFS, "nolazystatfs"}, + {LL_SBI_32BIT_API, "32bitapi"}, + {LL_SBI_USER_FID2PATH, "user_fid2path"}, + {LL_SBI_USER_FID2PATH, "nouser_fid2path"}, + {LL_SBI_VERBOSE, "verbose"}, + {LL_SBI_VERBOSE, "noverbose"}, + {LL_SBI_ALWAYS_PING, "always_ping"}, + {LL_SBI_TEST_DUMMY_ENCRYPTION, "test_dummy_encryption"}, + {LL_SBI_ENCRYPT, "encrypt"}, + {LL_SBI_ENCRYPT, "noencrypt"}, + {LL_SBI_FOREIGN_SYMLINK, "foreign_symlink=%s"}, + {LL_SBI_NUM_MOUNT_OPT, NULL}, + + {LL_SBI_ACL, "acl"}, + {LL_SBI_AGL_ENABLED, "agl"}, + {LL_SBI_64BIT_HASH, "64bit_hash"}, + {LL_SBI_LAYOUT_LOCK, "layout"}, + {LL_SBI_XATTR_CACHE, "xattr_cache"}, + {LL_SBI_NOROOTSQUASH, "norootsquash"}, + {LL_SBI_FAST_READ, "fast_read"}, + {LL_SBI_FILE_SECCTX, "file_secctx"}, + {LL_SBI_TINY_WRITE, "tiny_write"}, + {LL_SBI_FILE_HEAT, "file_heat"}, + {LL_SBI_PARALLEL_DIO, "parallel_dio"}, +}; + +int ll_sbi_flags_seq_show(struct seq_file *m, void *v) { - if (strncmp(opt, data, strlen(opt)) != 0) - return 0; - else - return fl; + struct super_block *sb = m->private; + int i; + + for (i = 0; i < LL_SBI_NUM_FLAGS; i++) { + int j; + + if (!test_bit(i, ll_s2sbi(sb)->ll_flags)) + continue; + + for (j = 0; j < ARRAY_SIZE(ll_sbi_flags_name); j++) { + if (ll_sbi_flags_name[j].token == i && + ll_sbi_flags_name[j].pattern) { + seq_printf(m, "%s ", + ll_sbi_flags_name[j].pattern); + break; + } + } + } + seq_puts(m, "\b\n"); + return 0; } /* non-client-specific mount options are parsed in lmd_parse */ -static int ll_options(char *options, struct ll_sb_info *sbi) +static int ll_options(char *options, struct super_block *sb) { - int tmp; - char *s1 = options, *s2; - int *flags = &sbi->ll_flags; - ENTRY; + struct ll_sb_info *sbi = ll_s2sbi(sb); + char *s2, *s1, *opts; + ENTRY; if (!options) RETURN(0); + /* Don't stomp on lmd_opts */ + opts = kstrdup(options, GFP_KERNEL); + if (!opts) + RETURN(-ENOMEM); + s1 = opts; + s2 = opts; + CDEBUG(D_CONFIG, "Parsing opts %s\n", options); - while (*s1) { + while ((s1 = strsep(&opts, ",")) != NULL) { + substring_t args[MAX_OPT_ARGS]; + bool turn_off = false; + int token; + + if (!*s1) + continue; + CDEBUG(D_SUPER, "next opt=%s\n", s1); - tmp = ll_set_opt("nolock", s1, LL_SBI_NOLCK); - if (tmp) { - *flags |= tmp; - goto next; - } - tmp = ll_set_opt("flock", s1, LL_SBI_FLOCK); - if (tmp) { - *flags = (*flags & ~LL_SBI_LOCALFLOCK) | tmp; - goto next; - } - tmp = ll_set_opt("localflock", s1, LL_SBI_LOCALFLOCK); - if (tmp) { - *flags = (*flags & ~LL_SBI_FLOCK) | tmp; - goto next; - } - tmp = ll_set_opt("noflock", s1, LL_SBI_FLOCK|LL_SBI_LOCALFLOCK); - if (tmp) { - *flags &= ~tmp; - goto next; - } - tmp = ll_set_opt("user_xattr", s1, LL_SBI_USER_XATTR); - if (tmp) { - *flags |= tmp; - goto next; - } - tmp = ll_set_opt("nouser_xattr", s1, LL_SBI_USER_XATTR); - if (tmp) { - *flags &= ~tmp; - goto next; - } - tmp = ll_set_opt("context", s1, 1); - if (tmp) - goto next; - tmp = ll_set_opt("fscontext", s1, 1); - if (tmp) - goto next; - tmp = ll_set_opt("defcontext", s1, 1); - if (tmp) - goto next; - tmp = ll_set_opt("rootcontext", s1, 1); - if (tmp) - goto next; - tmp = ll_set_opt("user_fid2path", s1, LL_SBI_USER_FID2PATH); - if (tmp) { - *flags |= tmp; - goto next; - } - tmp = ll_set_opt("nouser_fid2path", s1, LL_SBI_USER_FID2PATH); - if (tmp) { - *flags &= ~tmp; - goto next; - } - tmp = ll_set_opt("checksum", s1, LL_SBI_CHECKSUM); - if (tmp) { - *flags |= tmp; - sbi->ll_checksum_set = 1; - goto next; + if (strncmp(s1, "no", 2) == 0) + turn_off = true; + + /* + * Initialize args struct so we know whether arg was + * found; some options take optional arguments. + */ + args[0].to = NULL; + args[0].from = NULL; + token = match_token(s1, ll_sbi_flags_name, args); + if (token == LL_SBI_NUM_MOUNT_OPT) { + if (match_wildcard("context", s1) || + match_wildcard("fscontext", s1) || + match_wildcard("defcontext", s1) || + match_wildcard("rootcontext",s1)) + continue; + + LCONSOLE_ERROR_MSG(0x152, + "Unknown option '%s', won't mount.\n", + s1); + RETURN(-EINVAL); } - tmp = ll_set_opt("nochecksum", s1, LL_SBI_CHECKSUM); - if (tmp) { - *flags &= ~tmp; + + switch (token) { + case LL_SBI_NOLCK: + case LL_SBI_32BIT_API: + case LL_SBI_64BIT_HASH: + case LL_SBI_ALWAYS_PING: + set_bit(token, sbi->ll_flags); + break; + + case LL_SBI_FLOCK: + clear_bit(LL_SBI_LOCALFLOCK, sbi->ll_flags); + if (turn_off) + clear_bit(LL_SBI_FLOCK, sbi->ll_flags); + else + set_bit(token, sbi->ll_flags); + break; + + case LL_SBI_LOCALFLOCK: + clear_bit(LL_SBI_FLOCK, sbi->ll_flags); + set_bit(token, sbi->ll_flags); + break; + + case LL_SBI_CHECKSUM: sbi->ll_checksum_set = 1; - goto next; - } - tmp = ll_set_opt("lruresize", s1, LL_SBI_LRU_RESIZE); - if (tmp) { - *flags |= tmp; - goto next; - } - tmp = ll_set_opt("nolruresize", s1, LL_SBI_LRU_RESIZE); - if (tmp) { - *flags &= ~tmp; - goto next; - } - tmp = ll_set_opt("lazystatfs", s1, LL_SBI_LAZYSTATFS); - if (tmp) { - *flags |= tmp; - goto next; - } - tmp = ll_set_opt("nolazystatfs", s1, LL_SBI_LAZYSTATFS); - if (tmp) { - *flags &= ~tmp; - goto next; - } - tmp = ll_set_opt("32bitapi", s1, LL_SBI_32BIT_API); - if (tmp) { - *flags |= tmp; - goto next; - } - tmp = ll_set_opt("verbose", s1, LL_SBI_VERBOSE); - if (tmp) { - *flags |= tmp; - goto next; - } - tmp = ll_set_opt("noverbose", s1, LL_SBI_VERBOSE); - if (tmp) { - *flags &= ~tmp; - goto next; - } - tmp = ll_set_opt("always_ping", s1, LL_SBI_ALWAYS_PING); - if (tmp) { - *flags |= tmp; - goto next; - } - tmp = ll_set_opt("test_dummy_encryption", s1, - LL_SBI_TEST_DUMMY_ENCRYPTION); - if (tmp) { + /* fall through */ + case LL_SBI_USER_XATTR: + case LL_SBI_USER_FID2PATH: + case LL_SBI_LRU_RESIZE: + case LL_SBI_LAZYSTATFS: + case LL_SBI_VERBOSE: + if (turn_off) + clear_bit(token, sbi->ll_flags); + else + set_bit(token, sbi->ll_flags); + break; + case LL_SBI_TEST_DUMMY_ENCRYPTION: { #ifdef HAVE_LUSTRE_CRYPTO - *flags |= tmp; + set_bit(token, sbi->ll_flags); #else LCONSOLE_WARN("Test dummy encryption mount option ignored: encryption not supported\n"); #endif - goto next; + break; } - tmp = ll_set_opt("noencrypt", s1, LL_SBI_ENCRYPT); - if (tmp) { + case LL_SBI_ENCRYPT: #ifdef HAVE_LUSTRE_CRYPTO - *flags &= ~tmp; + if (turn_off) + clear_bit(token, sbi->ll_flags); + else + set_bit(token, sbi->ll_flags); #else - LCONSOLE_WARN("noencrypt mount option ignored: encryption not supported\n"); + LCONSOLE_WARN("noencrypt or encrypt mount option ignored: encryption not supported\n"); #endif - goto next; - } - tmp = ll_set_opt("foreign_symlink", s1, LL_SBI_FOREIGN_SYMLINK); - if (tmp) { - int prefix_pos = sizeof("foreign_symlink=") - 1; - int equal_pos = sizeof("foreign_symlink=") - 2; - + break; + case LL_SBI_FOREIGN_SYMLINK: /* non-default prefix provided ? */ - if (strlen(s1) >= sizeof("foreign_symlink=") && - *(s1 + equal_pos) == '=') { - char *old = sbi->ll_foreign_symlink_prefix; - size_t old_len = - sbi->ll_foreign_symlink_prefix_size; + if (args->from) { + size_t old_len; + char *old; /* path must be absolute */ - if (*(s1 + sizeof("foreign_symlink=") - - 1) != '/') { + if (args->from[0] != '/') { LCONSOLE_ERROR_MSG(0x152, - "foreign prefix '%s' must be an absolute path\n", - s1 + prefix_pos); + "foreign prefix '%s' must be an absolute path\n", + args->from); RETURN(-EINVAL); } - /* last option ? */ - s2 = strchrnul(s1 + prefix_pos, ','); - if (sbi->ll_foreign_symlink_prefix) { - sbi->ll_foreign_symlink_prefix = NULL; - sbi->ll_foreign_symlink_prefix_size = 0; - } + old_len = sbi->ll_foreign_symlink_prefix_size; + old = sbi->ll_foreign_symlink_prefix; /* alloc for path length and '\0' */ - OBD_ALLOC(sbi->ll_foreign_symlink_prefix, - s2 - (s1 + prefix_pos) + 1); + sbi->ll_foreign_symlink_prefix = match_strdup(args); if (!sbi->ll_foreign_symlink_prefix) { /* restore previous */ sbi->ll_foreign_symlink_prefix = old; @@ -1076,32 +1090,26 @@ static int ll_options(char *options, struct ll_sb_info *sbi) old_len; RETURN(-ENOMEM); } + sbi->ll_foreign_symlink_prefix_size = + args->to - args->from + 1; + OBD_ALLOC_POST(sbi->ll_foreign_symlink_prefix, + sbi->ll_foreign_symlink_prefix_size, + "kmalloced"); if (old) OBD_FREE(old, old_len); - strncpy(sbi->ll_foreign_symlink_prefix, - s1 + prefix_pos, - s2 - (s1 + prefix_pos)); - sbi->ll_foreign_symlink_prefix_size = - s2 - (s1 + prefix_pos) + 1; + + /* enable foreign symlink support */ + set_bit(token, sbi->ll_flags); } else { LCONSOLE_ERROR_MSG(0x152, "invalid %s option\n", s1); } - /* enable foreign symlink support */ - *flags |= tmp; - goto next; + /* fall through */ + default: + break; } - LCONSOLE_ERROR_MSG(0x152, "Unknown option '%s', won't mount.\n", - s1); - RETURN(-EINVAL); - -next: - /* Find next opt */ - s2 = strchr(s1, ','); - if (s2 == NULL) - break; - s1 = s2 + 1; } + kfree(opts); RETURN(0); } @@ -1236,7 +1244,7 @@ int ll_fill_super(struct super_block *sb) if (IS_ERR(sbi)) GOTO(out_free_cfg, err = PTR_ERR(sbi)); - err = ll_options(lsi->lsi_lmd->lmd_opts, sbi); + err = ll_options(lsi->lsi_lmd->lmd_opts, sb); if (err) GOTO(out_free_cfg, err); @@ -1346,7 +1354,7 @@ out_free_cfg: if (err) ll_put_super(sb); - else if (sbi->ll_flags & LL_SBI_VERBOSE) + else if (test_bit(LL_SBI_VERBOSE, sbi->ll_flags)) LCONSOLE_WARN("Mounted %s\n", profilenm); RETURN(err); } /* ll_fill_super */ @@ -1413,7 +1421,7 @@ void ll_put_super(struct super_block *sb) while ((obd = class_devices_in_group(&sbi->ll_sb_uuid, &next))) class_manual_cleanup(obd); - if (sbi->ll_flags & LL_SBI_VERBOSE) + if (test_bit(LL_SBI_VERBOSE, sbi->ll_flags)) LCONSOLE_WARN("Unmounted %s\n", profilenm ? profilenm : ""); if (profilenm) @@ -1491,7 +1499,7 @@ static struct inode *ll_iget_anon_dir(struct super_block *sb, ENTRY; LASSERT(md->lmv); - ino = cl_fid_build_ino(fid, sbi->ll_flags & LL_SBI_32BIT_API); + ino = cl_fid_build_ino(fid, test_bit(LL_SBI_32BIT_API, sbi->ll_flags)); inode = iget_locked(sb, ino); if (inode == NULL) { CERROR("%s: failed get simple inode "DFID": rc = -ENOENT\n", @@ -2290,7 +2298,7 @@ int ll_statfs_internal(struct ll_sb_info *sbi, struct obd_statfs *osfs, ENTRY; max_age = ktime_get_seconds() - sbi->ll_statfs_max_age; - if (sbi->ll_flags & LL_SBI_LAZYSTATFS) + if (test_bit(LL_SBI_LAZYSTATFS, sbi->ll_flags)) flags |= OBD_STATFS_NODELAY; rc = obd_statfs(NULL, sbi->ll_md_exp, osfs, max_age, flags); @@ -2458,6 +2466,7 @@ int ll_update_inode(struct inode *inode, struct lustre_md *md) struct ll_inode_info *lli = ll_i2info(inode); struct mdt_body *body = md->body; struct ll_sb_info *sbi = ll_i2sbi(inode); + bool api32; int rc = 0; if (body->mbo_valid & OBD_MD_FLEASIZE) { @@ -2475,8 +2484,8 @@ int ll_update_inode(struct inode *inode, struct lustre_md *md) if (body->mbo_valid & OBD_MD_FLACL) lli_replace_acl(lli, md); - inode->i_ino = cl_fid_build_ino(&body->mbo_fid1, - sbi->ll_flags & LL_SBI_32BIT_API); + api32 = test_bit(LL_SBI_32BIT_API, sbi->ll_flags); + inode->i_ino = cl_fid_build_ino(&body->mbo_fid1, api32); inode->i_generation = cl_fid_build_gen(&body->mbo_fid1); if (body->mbo_valid & OBD_MD_FLATIME) { @@ -2882,7 +2891,7 @@ int ll_remount_fs(struct super_block *sb, int *flags, char *data) else sb->s_flags &= ~SB_RDONLY; - if (sbi->ll_flags & LL_SBI_VERBOSE) + if (test_bit(LL_SBI_VERBOSE, sbi->ll_flags)) LCONSOLE_WARN("Remounted %s %s\n", profilenm, read_only ? "read-only" : "read-write"); } @@ -2962,22 +2971,22 @@ int ll_prep_inode(struct inode **inode, struct req_capsule *pill, if (rc != 0) GOTO(out, rc); } else { + bool api32 = test_bit(LL_SBI_32BIT_API, sbi->ll_flags); + struct lu_fid *fid1 = &md.body->mbo_fid1; + LASSERT(sb != NULL); /* * At this point server returns to client's same fid as client * generated for creating. So using ->fid1 is okay here. */ - if (!fid_is_sane(&md.body->mbo_fid1)) { + if (!fid_is_sane(fid1)) { CERROR("%s: Fid is insane "DFID"\n", - sbi->ll_fsname, - PFID(&md.body->mbo_fid1)); + sbi->ll_fsname, PFID(fid1)); GOTO(out, rc = -EINVAL); } - *inode = ll_iget(sb, cl_fid_build_ino(&md.body->mbo_fid1, - sbi->ll_flags & LL_SBI_32BIT_API), - &md); + *inode = ll_iget(sb, cl_fid_build_ino(fid1, api32), &md); if (IS_ERR(*inode)) { lmd_clear_acl(&md); rc = IS_ERR(*inode) ? PTR_ERR(*inode) : -ENOMEM; @@ -3158,7 +3167,7 @@ struct md_op_data *ll_prep_md_op_data(struct md_op_data *op_data, fid_zero(&op_data->op_fid2); } - if (ll_i2sbi(i1)->ll_flags & LL_SBI_64BIT_HASH) + if (test_bit(LL_SBI_64BIT_HASH, ll_i2sbi(i1)->ll_flags)) op_data->op_cli_flags |= CLI_HASH64; if (ll_need_32bit_api(ll_i2sbi(i1))) @@ -3245,47 +3254,40 @@ void ll_finish_md_op_data(struct md_op_data *op_data) int ll_show_options(struct seq_file *seq, struct dentry *dentry) { struct ll_sb_info *sbi; + int i; LASSERT(seq && dentry); sbi = ll_s2sbi(dentry->d_sb); - if (sbi->ll_flags & LL_SBI_NOLCK) - seq_puts(seq, ",nolock"); - - /* "flock" is the default since 2.13, but it wasn't for many years, - * so it is still useful to print this to show it is enabled. - * Start to print "noflock" so it is now clear when flock is disabled. - */ - if (sbi->ll_flags & LL_SBI_FLOCK) - seq_puts(seq, ",flock"); - else if (sbi->ll_flags & LL_SBI_LOCALFLOCK) - seq_puts(seq, ",localflock"); - else - seq_puts(seq, ",noflock"); - - if (sbi->ll_flags & LL_SBI_USER_XATTR) - seq_puts(seq, ",user_xattr"); - - if (sbi->ll_flags & LL_SBI_LAZYSTATFS) - seq_puts(seq, ",lazystatfs"); - - if (sbi->ll_flags & LL_SBI_USER_FID2PATH) - seq_puts(seq, ",user_fid2path"); + if (test_bit(LL_SBI_NOLCK, sbi->ll_flags)) + seq_puts(seq, "nolock"); - if (sbi->ll_flags & LL_SBI_ALWAYS_PING) - seq_puts(seq, ",always_ping"); - - if (ll_sbi_has_test_dummy_encryption(sbi)) - seq_puts(seq, ",test_dummy_encryption"); - - if (ll_sbi_has_encrypt(sbi)) - seq_puts(seq, ",encrypt"); - else - seq_puts(seq, ",noencrypt"); + for (i = 1; ll_sbi_flags_name[i].token != LL_SBI_NUM_MOUNT_OPT; i++) { + /* match_table in some cases has patterns for both enabled and + * disabled cases. Ignore 'no'xxx versions if bit is set. + */ + if (test_bit(ll_sbi_flags_name[i].token, sbi->ll_flags) && + strncmp(ll_sbi_flags_name[i].pattern, "no", 2)) { + if (ll_sbi_flags_name[i].token == + LL_SBI_FOREIGN_SYMLINK) { + seq_show_option(seq, "foreign_symlink", + sbi->ll_foreign_symlink_prefix); + } else { + seq_printf(seq, ",%s", + ll_sbi_flags_name[i].pattern); + } - if (sbi->ll_flags & LL_SBI_FOREIGN_SYMLINK) { - seq_puts(seq, ",foreign_symlink="); - seq_puts(seq, sbi->ll_foreign_symlink_prefix); + /* You can have either localflock or flock but not + * both. If localflock is set don't print flock or + * noflock. + */ + if (ll_sbi_flags_name[i].token == LL_SBI_LOCALFLOCK) + i += 2; + } else if (!test_bit(ll_sbi_flags_name[i].token, sbi->ll_flags) && + !strncmp(ll_sbi_flags_name[i].pattern, "no", 2)) { + seq_printf(seq, ",%s", + ll_sbi_flags_name[i].pattern); + } } RETURN(0); @@ -3400,7 +3402,7 @@ void ll_compute_rootsquash_state(struct ll_sb_info *sbi) /* Update norootsquash flag */ spin_lock(&squash->rsi_lock); if (list_empty(&squash->rsi_nosquash_nids)) - sbi->ll_flags &= ~LL_SBI_NOROOTSQUASH; + clear_bit(LL_SBI_NOROOTSQUASH, sbi->ll_flags); else { /* Do not apply root squash as soon as one of our NIDs is * in the nosquash_nids list */ @@ -3415,9 +3417,9 @@ void ll_compute_rootsquash_state(struct ll_sb_info *sbi) } } if (matched) - sbi->ll_flags |= LL_SBI_NOROOTSQUASH; + set_bit(LL_SBI_NOROOTSQUASH, sbi->ll_flags); else - sbi->ll_flags &= ~LL_SBI_NOROOTSQUASH; + clear_bit(LL_SBI_NOROOTSQUASH, sbi->ll_flags); } spin_unlock(&squash->rsi_lock); } @@ -3491,7 +3493,7 @@ int ll_getparent(struct file *file, struct getparent __user *arg) ENTRY; if (!capable(CAP_DAC_READ_SEARCH) && - !(ll_i2sbi(inode)->ll_flags & LL_SBI_USER_FID2PATH)) + !test_bit(LL_SBI_USER_FID2PATH, ll_i2sbi(inode)->ll_flags)) RETURN(-EPERM); if (get_user(name_size, &arg->gp_name_size)) diff --git a/lustre/llite/lproc_llite.c b/lustre/llite/lproc_llite.c index 7505403..c57be4e 100644 --- a/lustre/llite/lproc_llite.c +++ b/lustre/llite/lproc_llite.c @@ -602,7 +602,8 @@ static ssize_t checksums_show(struct kobject *kobj, struct attribute *attr, struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info, ll_kset.kobj); - return sprintf(buf, "%u\n", (sbi->ll_flags & LL_SBI_CHECKSUM) ? 1 : 0); + return scnprintf(buf, PAGE_SIZE, "%u\n", + test_bit(LL_SBI_CHECKSUM, sbi->ll_flags)); } static ssize_t checksums_store(struct kobject *kobj, struct attribute *attr, @@ -622,9 +623,9 @@ static ssize_t checksums_store(struct kobject *kobj, struct attribute *attr, if (rc) return rc; if (val) - sbi->ll_flags |= LL_SBI_CHECKSUM; + set_bit(LL_SBI_CHECKSUM, sbi->ll_flags); else - sbi->ll_flags &= ~LL_SBI_CHECKSUM; + clear_bit(LL_SBI_CHECKSUM, sbi->ll_flags); tmp = val; rc = obd_set_info_async(NULL, sbi->ll_dt_exp, sizeof(KEY_CHECKSUM), @@ -798,7 +799,8 @@ static ssize_t statahead_agl_show(struct kobject *kobj, struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info, ll_kset.kobj); - return sprintf(buf, "%u\n", sbi->ll_flags & LL_SBI_AGL_ENABLED ? 1 : 0); + return scnprintf(buf, PAGE_SIZE, "%u\n", + test_bit(LL_SBI_AGL_ENABLED, sbi->ll_flags)); } static ssize_t statahead_agl_store(struct kobject *kobj, @@ -816,9 +818,9 @@ static ssize_t statahead_agl_store(struct kobject *kobj, return rc; if (val) - sbi->ll_flags |= LL_SBI_AGL_ENABLED; + set_bit(LL_SBI_AGL_ENABLED, sbi->ll_flags); else - sbi->ll_flags &= ~LL_SBI_AGL_ENABLED; + clear_bit(LL_SBI_AGL_ENABLED, sbi->ll_flags); return count; } @@ -847,7 +849,8 @@ static ssize_t lazystatfs_show(struct kobject *kobj, struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info, ll_kset.kobj); - return sprintf(buf, "%u\n", (sbi->ll_flags & LL_SBI_LAZYSTATFS) ? 1 : 0); + return scnprintf(buf, PAGE_SIZE, "%u\n", + test_bit(LL_SBI_LAZYSTATFS, sbi->ll_flags)); } static ssize_t lazystatfs_store(struct kobject *kobj, @@ -865,9 +868,9 @@ static ssize_t lazystatfs_store(struct kobject *kobj, return rc; if (val) - sbi->ll_flags |= LL_SBI_LAZYSTATFS; + set_bit(LL_SBI_LAZYSTATFS, sbi->ll_flags); else - sbi->ll_flags &= ~LL_SBI_LAZYSTATFS; + clear_bit(LL_SBI_LAZYSTATFS, sbi->ll_flags); return count; } @@ -992,29 +995,6 @@ static ssize_t default_easize_store(struct kobject *kobj, } LUSTRE_RW_ATTR(default_easize); -static int ll_sbi_flags_seq_show(struct seq_file *m, void *v) -{ - const char *const str[] = LL_SBI_FLAGS; - struct super_block *sb = m->private; - int flags = ll_s2sbi(sb)->ll_flags; - int i = 0; - - while (flags != 0) { - if (ARRAY_SIZE(str) <= i) { - CERROR("%s: Revise array LL_SBI_FLAGS to match sbi " - "flags please.\n", ll_s2sbi(sb)->ll_fsname); - return -EINVAL; - } - - if (flags & 0x1) - seq_printf(m, "%s ", str[i]); - flags >>= 1; - ++i; - } - seq_printf(m, "\b\n"); - return 0; -} - LDEBUGFS_SEQ_FOPS_RO(ll_sbi_flags); static ssize_t xattr_cache_show(struct kobject *kobj, @@ -1041,7 +1021,7 @@ static ssize_t xattr_cache_store(struct kobject *kobj, if (rc) return rc; - if (val && !(sbi->ll_flags & LL_SBI_XATTR_CACHE)) + if (val && !test_bit(LL_SBI_XATTR_CACHE, sbi->ll_flags)) return -ENOTSUPP; sbi->ll_xattr_cache_enabled = val; @@ -1058,7 +1038,8 @@ static ssize_t tiny_write_show(struct kobject *kobj, struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info, ll_kset.kobj); - return sprintf(buf, "%u\n", !!(sbi->ll_flags & LL_SBI_TINY_WRITE)); + return scnprintf(buf, PAGE_SIZE, "%u\n", + test_bit(LL_SBI_TINY_WRITE, sbi->ll_flags)); } static ssize_t tiny_write_store(struct kobject *kobj, @@ -1077,9 +1058,9 @@ static ssize_t tiny_write_store(struct kobject *kobj, spin_lock(&sbi->ll_lock); if (val) - sbi->ll_flags |= LL_SBI_TINY_WRITE; + set_bit(LL_SBI_TINY_WRITE, sbi->ll_flags); else - sbi->ll_flags &= ~LL_SBI_TINY_WRITE; + clear_bit(LL_SBI_TINY_WRITE, sbi->ll_flags); spin_unlock(&sbi->ll_lock); return count; @@ -1094,7 +1075,7 @@ static ssize_t parallel_dio_show(struct kobject *kobj, ll_kset.kobj); return snprintf(buf, PAGE_SIZE, "%u\n", - !!(sbi->ll_flags & LL_SBI_PARALLEL_DIO)); + test_bit(LL_SBI_PARALLEL_DIO, sbi->ll_flags)); } static ssize_t parallel_dio_store(struct kobject *kobj, @@ -1113,9 +1094,9 @@ static ssize_t parallel_dio_store(struct kobject *kobj, spin_lock(&sbi->ll_lock); if (val) - sbi->ll_flags |= LL_SBI_PARALLEL_DIO; + set_bit(LL_SBI_PARALLEL_DIO, sbi->ll_flags); else - sbi->ll_flags &= ~LL_SBI_PARALLEL_DIO; + clear_bit(LL_SBI_PARALLEL_DIO, sbi->ll_flags); spin_unlock(&sbi->ll_lock); return count; @@ -1260,7 +1241,8 @@ static ssize_t fast_read_show(struct kobject *kobj, struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info, ll_kset.kobj); - return sprintf(buf, "%u\n", !!(sbi->ll_flags & LL_SBI_FAST_READ)); + return scnprintf(buf, PAGE_SIZE, "%u\n", + test_bit(LL_SBI_FAST_READ, sbi->ll_flags)); } static ssize_t fast_read_store(struct kobject *kobj, @@ -1279,9 +1261,9 @@ static ssize_t fast_read_store(struct kobject *kobj, spin_lock(&sbi->ll_lock); if (val) - sbi->ll_flags |= LL_SBI_FAST_READ; + set_bit(LL_SBI_FAST_READ, sbi->ll_flags); else - sbi->ll_flags &= ~LL_SBI_FAST_READ; + clear_bit(LL_SBI_FAST_READ, sbi->ll_flags); spin_unlock(&sbi->ll_lock); return count; @@ -1296,7 +1278,7 @@ static ssize_t file_heat_show(struct kobject *kobj, ll_kset.kobj); return scnprintf(buf, PAGE_SIZE, "%u\n", - !!(sbi->ll_flags & LL_SBI_FILE_HEAT)); + test_bit(LL_SBI_FILE_HEAT, sbi->ll_flags)); } static ssize_t file_heat_store(struct kobject *kobj, @@ -1315,9 +1297,9 @@ static ssize_t file_heat_store(struct kobject *kobj, spin_lock(&sbi->ll_lock); if (val) - sbi->ll_flags |= LL_SBI_FILE_HEAT; + set_bit(LL_SBI_FILE_HEAT, sbi->ll_flags); else - sbi->ll_flags &= ~LL_SBI_FILE_HEAT; + clear_bit(LL_SBI_FILE_HEAT, sbi->ll_flags); spin_unlock(&sbi->ll_lock); return count; diff --git a/lustre/llite/namei.c b/lustre/llite/namei.c index cdac373..e5540d3d 100644 --- a/lustre/llite/namei.c +++ b/lustre/llite/namei.c @@ -889,7 +889,7 @@ static struct dentry *ll_lookup_it(struct inode *parent, struct dentry *dentry, it->it_create_mode &= ~current_umask(); if (it->it_op & IT_CREAT && - ll_i2sbi(parent)->ll_flags & LL_SBI_FILE_SECCTX) { + test_bit(LL_SBI_FILE_SECCTX, ll_i2sbi(parent)->ll_flags)) { rc = ll_dentry_init_security(dentry, it->it_create_mode, &dentry->d_name, &op_data->op_file_secctx_name, @@ -1427,8 +1427,8 @@ static int ll_create_it(struct inode *dir, struct dentry *dentry, if (IS_ERR(inode)) RETURN(PTR_ERR(inode)); - if ((ll_i2sbi(inode)->ll_flags & LL_SBI_FILE_SECCTX) && - secctx != NULL) { + if (test_bit(LL_SBI_FILE_SECCTX, ll_i2sbi(inode)->ll_flags) && + secctx) { /* must be done before d_instantiate, because it calls * security_d_instantiate, which means a getxattr if security * context is not set yet */ @@ -1449,7 +1449,7 @@ static int ll_create_it(struct inode *dir, struct dentry *dentry, RETURN(rc); } - if (!(ll_i2sbi(inode)->ll_flags & LL_SBI_FILE_SECCTX)) { + if (!test_bit(LL_SBI_FILE_SECCTX, ll_i2sbi(inode)->ll_flags)) { rc = ll_inode_init_security(dentry, inode, dir); if (rc) RETURN(rc); @@ -1565,7 +1565,7 @@ again: if (S_ISDIR(mode)) ll_qos_mkdir_prep(op_data, dir); - if (sbi->ll_flags & LL_SBI_FILE_SECCTX) { + if (test_bit(LL_SBI_FILE_SECCTX, sbi->ll_flags)) { err = ll_dentry_init_security(dchild, mode, &dchild->d_name, &op_data->op_file_secctx_name, &op_data->op_file_secctx, @@ -1706,7 +1706,7 @@ again: if (err) GOTO(err_exit, err); - if (sbi->ll_flags & LL_SBI_FILE_SECCTX) { + if (test_bit(LL_SBI_FILE_SECCTX, sbi->ll_flags)) { /* must be done before d_instantiate, because it calls * security_d_instantiate, which means a getxattr if security * context is not set yet */ @@ -1745,7 +1745,7 @@ again: } } - if (!(sbi->ll_flags & LL_SBI_FILE_SECCTX)) { + if (!test_bit(LL_SBI_FILE_SECCTX, sbi->ll_flags)) { err = ll_inode_init_security(dchild, inode, dir); if (err) GOTO(err_exit, err); diff --git a/lustre/llite/statahead.c b/lustre/llite/statahead.c index cddd37e..48deda0 100644 --- a/lustre/llite/statahead.c +++ b/lustre/llite/statahead.c @@ -1685,7 +1685,8 @@ static int start_statahead_thread(struct inode *dir, struct dentry *dentry, GOTO(out, rc); } - if (ll_i2sbi(parent->d_inode)->ll_flags & LL_SBI_AGL_ENABLED && agl) + if (test_bit(LL_SBI_AGL_ENABLED, ll_i2sbi(parent->d_inode)->ll_flags) && + agl) ll_start_agl(parent, sai); atomic_inc(&ll_i2sbi(parent->d_inode)->ll_sa_total); diff --git a/lustre/llite/xattr.c b/lustre/llite/xattr.c index 779e6e0..ca45354 100644 --- a/lustre/llite/xattr.c +++ b/lustre/llite/xattr.c @@ -76,11 +76,11 @@ static int xattr_type_filter(struct ll_sb_info *sbi, if ((handler->flags == XATTR_ACL_ACCESS_T || handler->flags == XATTR_ACL_DEFAULT_T) && - !(sbi->ll_flags & LL_SBI_ACL)) + !test_bit(LL_SBI_ACL, sbi->ll_flags)) return -EOPNOTSUPP; if (handler->flags == XATTR_USER_T && - !(sbi->ll_flags & LL_SBI_USER_XATTR)) + !test_bit(LL_SBI_USER_XATTR, sbi->ll_flags)) return -EOPNOTSUPP; if (handler->flags == XATTR_TRUSTED_T && @@ -167,7 +167,7 @@ static int ll_xattr_set_common(const struct xattr_handler *handler, if (rc) { if (rc == -EOPNOTSUPP && handler->flags == XATTR_USER_T) { LCONSOLE_INFO("Disabling user_xattr feature because it is not supported on the server\n"); - sbi->ll_flags &= ~LL_SBI_USER_XATTR; + clear_bit(LL_SBI_USER_XATTR, sbi->ll_flags); } RETURN(rc); } @@ -442,7 +442,7 @@ out_xattr: LCONSOLE_INFO("%s: disabling user_xattr feature because " "it is not supported on the server: rc = %d\n", sbi->ll_fsname, rc); - sbi->ll_flags &= ~LL_SBI_USER_XATTR; + clear_bit(LL_SBI_USER_XATTR, sbi->ll_flags); } out: ptlrpc_req_finished(req); -- 1.8.3.1