* -- I am the owner of dir statahead. */
pid_t lli_opendir_pid;
/* directory depth to ROOT */
- unsigned short lli_depth;
+ unsigned short lli_dir_depth;
+ /* directory depth to ancestor whose default LMV is
+ * inherited.
+ */
+ unsigned short lli_inherit_depth;
/* stat will try to access statahead entries or start
* statahead if this flag is set, and this flag will be
* set upon dir open, and cleared when dir is closed,
struct list_head lli_lccs; /* list of ll_cl_context */
};
+#ifndef HAVE_USER_NAMESPACE_ARG
+#define inode_permission(ns, inode, mask) inode_permission(inode, mask)
+#define generic_permission(ns, inode, mask) generic_permission(inode, mask)
+#define simple_setattr(ns, de, iattr) simple_setattr(de, iattr)
+#define ll_inode_permission(ns, inode, mask) ll_inode_permission(inode, mask)
+#ifdef HAVE_INODEOPS_ENHANCED_GETATTR
+#define ll_getattr(ns, path, stat, mask, fl) ll_getattr(path, stat, mask, fl)
+#endif /* HAVE_INODEOPS_ENHANCED_GETATTR */
+#define ll_setattr(ns, de, attr) ll_setattr(de, attr)
+#endif
+
static inline void ll_trunc_sem_init(struct ll_trunc_sem *sem)
{
atomic_set(&sem->ll_trunc_readers, 0);
static inline void trunc_sem_up_write(struct ll_trunc_sem *sem)
{
atomic_set(&sem->ll_trunc_readers, 0);
+ /* match the smp_mb() in wait_var_event()->prepare_to_wait() */
+ smp_mb();
wake_up_var(&sem->ll_trunc_readers);
}
LLIF_UPDATE_ATIME = 4,
/* foreign file/dir can be unlinked unconditionnaly */
LLIF_FOREIGN_REMOVABLE = 5,
- /* setting encryption context in progress */
- LLIF_SET_ENC_CTX = 6,
/* Xattr cache is filled */
LLIF_XATTR_CACHE_FILLED = 7,
#endif
}
+static inline bool obd_connect_has_name_enc(struct obd_connect_data *data)
+{
+#ifdef HAVE_LUSTRE_CRYPTO
+ return data->ocd_connect_flags & OBD_CONNECT_FLAGS2 &&
+ data->ocd_connect_flags2 & OBD_CONNECT2_ENCRYPT_NAME;
+#else
+ return false;
+#endif
+}
+
+static inline void obd_connect_set_name_enc(struct obd_connect_data *data)
+{
+#ifdef HAVE_LUSTRE_CRYPTO
+ data->ocd_connect_flags2 |= OBD_CONNECT2_ENCRYPT_NAME;
+#endif
+}
+
/*
* Locking to guarantee consistency of non-atomic updates to long long i_size,
* consistency between file size and KMS.
#define LL_HIST_START 12 /* buckets start at 2^12 = 4k */
#define LL_PROCESS_HIST_MAX 10
struct per_process_info {
- pid_t pid;
- struct obd_histogram pp_r_hist;
- struct obd_histogram pp_w_hist;
+ pid_t pid;
+ struct obd_histogram pp_r_hist;
+ struct obd_histogram pp_w_hist;
};
/* pp_extents[LL_PROCESS_HIST_MAX] will hold the combined process info */
struct ll_rw_extents_info {
- struct per_process_info pp_extents[LL_PROCESS_HIST_MAX + 1];
+ ktime_t pp_init;
+ struct per_process_info pp_extents[LL_PROCESS_HIST_MAX + 1];
};
#define LL_OFFSET_HIST_MAX 100
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_ENCRYPT_NAME, /* name encryption */
LL_SBI_NUM_FLAGS
};
struct obd_device *ll_dt_obd;
struct dentry *ll_debugfs_entry;
struct lu_fid ll_root_fid; /* root object fid */
+ struct mnt_namespace *ll_mnt_ns;
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;
+ ll_checksum_set:1,
+ ll_inode_cache_enabled:1;
struct lustre_client_ocd ll_lco;
struct lu_site *ll_site;
struct cl_device *ll_cl;
+
/* Statistics */
- struct ll_rw_extents_info ll_rw_extents_info;
- int ll_extent_process_count;
- struct ll_rw_process_info ll_rw_process_info[LL_PROCESS_HIST_MAX];
- unsigned int ll_offset_process_count;
- struct ll_rw_process_info ll_rw_offset_info[LL_OFFSET_HIST_MAX];
- unsigned int ll_rw_offset_entry_count;
- int ll_stats_track_id;
- enum stats_track_type ll_stats_track_type;
- int ll_rw_stats_on;
+ struct ll_rw_extents_info *ll_rw_extents_info;
+ int ll_extent_process_count;
+ unsigned int ll_offset_process_count;
+ struct ll_rw_process_info *ll_rw_process_info;
+ struct ll_rw_process_info *ll_rw_offset_info;
+ ktime_t ll_process_stats_init;
+ unsigned int ll_rw_offset_entry_count;
+ int ll_stats_track_id;
+ enum stats_track_type ll_stats_track_type;
+ int ll_rw_stats_on;
/* metadata stat-ahead */
unsigned int ll_sa_running_max;/* max concurrent
struct file *lrw_file;
pgoff_t lrw_start_idx;
pgoff_t lrw_end_idx;
+ pid_t lrw_user_pid;
/* async worker to handler read */
struct work_struct lrw_readahead_work;
* layout version for verification to OST objects */
__u32 fd_layout_version;
struct pcc_file fd_pcc_file;
+ /* striped directory may read partially if some stripe inaccessible,
+ * -errno is saved here, and will return to user in close().
+ */
+ int fd_partial_readdir_rc;
};
void llite_tunables_unregister(void);
int ll_debugfs_register_super(struct super_block *sb, const char *name);
void ll_debugfs_unregister_super(struct super_block *sb);
void ll_stats_ops_tally(struct ll_sb_info *sbi, int op, long count);
+void ll_free_rw_stats_info(struct ll_sb_info *sbi);
enum {
LPROC_LL_READ_BYTES,
extern const struct inode_operations ll_dir_inode_operations;
#ifdef HAVE_DIR_CONTEXT
int ll_dir_read(struct inode *inode, __u64 *pos, struct md_op_data *op_data,
- struct dir_context *ctx);
+ struct dir_context *ctx, int *partial_readdir_rc);
#else
int ll_dir_read(struct inode *inode, __u64 *pos, struct md_op_data *op_data,
- void *cookie, filldir_t filldir);
+ void *cookie, filldir_t filldir, int *partial_readdir_rc);
#endif
int ll_get_mdt_idx(struct inode *inode);
int ll_get_mdt_idx_by_fid(struct ll_sb_info *sbi, const struct lu_fid *fid);
struct page *ll_get_dir_page(struct inode *dir, struct md_op_data *op_data,
- __u64 offset);
+ __u64 offset, int *partial_readdir_rc);
void ll_release_page(struct inode *inode, struct page *page, bool remove);
int quotactl_ioctl(struct super_block *sb, struct if_quotactl *qctl);
extern void ll_rw_stats_tally(struct ll_sb_info *sbi, pid_t pid,
struct ll_file_data *file, loff_t pos,
size_t count, int rw);
-#ifdef HAVE_INODEOPS_ENHANCED_GETATTR
-int ll_getattr(const struct path *path, struct kstat *stat,
- u32 request_mask, unsigned int flags);
+#if defined(HAVE_USER_NAMESPACE_ARG) || defined(HAVE_INODEOPS_ENHANCED_GETATTR)
+int ll_getattr(struct user_namespace *mnt_userns, const struct path *path,
+ struct kstat *stat, u32 request_mask, unsigned int flags);
#else
int ll_getattr(struct vfsmount *mnt, struct dentry *de, struct kstat *stat);
-#endif
+#endif /* HAVE_USER_NAMESPACE_ARG */
int ll_getattr_dentry(struct dentry *de, struct kstat *stat, u32 request_mask,
unsigned int flags, bool foreign);
#ifdef CONFIG_LUSTRE_FS_POSIX_ACL
-struct posix_acl *ll_get_acl(struct inode *inode, int type);
-int ll_set_acl(struct inode *inode, struct posix_acl *acl, int type);
+struct posix_acl *ll_get_acl(struct inode *inode, int type
+#ifdef HAVE_GET_ACL_RCU_ARG
+ , bool rcu
+#endif /* HAVE_GET_ACL_RCU_ARG */
+ );
+int ll_set_acl(struct user_namespace *mnt_userns, struct inode *inode,
+ struct posix_acl *acl, int type);
#else /* !CONFIG_LUSTRE_FS_POSIX_ACL */
#define ll_get_acl NULL
#define ll_set_acl NULL
}
int ll_migrate(struct inode *parent, struct file *file,
- struct lmv_user_md *lum, const char *name);
+ struct lmv_user_md *lum, const char *name, __u32 flags);
int ll_get_fid_by_name(struct inode *parent, const char *name,
int namelen, struct lu_fid *fid, struct inode **inode);
-int ll_inode_permission(struct inode *inode, int mask);
+int ll_inode_permission(struct user_namespace *mnt_userns, struct inode *inode,
+ int mask);
int ll_ioctl_check_project(struct inode *inode, __u32 xflags, __u32 projid);
int ll_ioctl_fsgetxattr(struct inode *inode, unsigned int cmd,
unsigned long arg);
struct ptlrpc_request **request);
int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump,
int set_default);
+int ll_dir_get_default_layout(struct inode *inode, void **plmm, int *plmm_size,
+ struct ptlrpc_request **request, u64 valid,
+ enum get_default_layout_type type);
int ll_dir_getstripe_default(struct inode *inode, void **lmmp,
int *lmm_size, struct ptlrpc_request **request,
struct ptlrpc_request **root_request, u64 valid);
struct inode *ll_inode_from_resource_lock(struct ldlm_lock *lock);
void ll_dir_clear_lsm_md(struct inode *inode);
void ll_clear_inode(struct inode *inode);
+int volatile_ref_file(const char *volatile_name, int volatile_len,
+ struct file **ref_file);
int ll_setattr_raw(struct dentry *dentry, struct iattr *attr,
enum op_xvalid xvalid, bool hsm_import);
-int ll_setattr(struct dentry *de, struct iattr *attr);
+int ll_setattr(struct user_namespace *mnt_userns, struct dentry *de,
+ struct iattr *attr);
int ll_statfs(struct dentry *de, struct kstatfs *sfs);
int ll_statfs_internal(struct ll_sb_info *sbi, struct obd_statfs *osfs,
u32 flags);
void ll_umount_begin(struct super_block *sb);
int ll_remount_fs(struct super_block *sb, int *flags, char *data);
int ll_show_options(struct seq_file *seq, struct dentry *dentry);
-void ll_dirty_page_discard_warn(struct page *page, int ioret);
+void ll_dirty_page_discard_warn(struct inode *inode, int ioret);
int ll_prep_inode(struct inode **inode, struct req_capsule *pill,
struct super_block *sb, struct lookup_intent *it);
int ll_obd_statfs(struct inode *inode, void __user *arg);
struct cl_io *lcc_io;
struct cl_page *lcc_page;
enum lcc_type lcc_type;
- /**
- * Get encryption context operation in progress,
- * allow getxattr of LL_XATTR_NAME_ENCRYPTION_CONTEXT xattr
- */
- unsigned lcc_getencctx:1;
};
struct ll_thread_info {
static inline bool ll_dir_striped(struct inode *inode)
{
+ struct ll_inode_info *lli;
+ bool rc;
+
LASSERT(inode);
- return S_ISDIR(inode->i_mode) &&
- lmv_dir_striped(ll_i2info(inode)->lli_lsm_md);
+ if (!S_ISDIR(inode->i_mode))
+ return false;
+
+ lli = ll_i2info(inode);
+ if (!lli->lli_lsm_md)
+ return false;
+
+ down_read(&lli->lli_lsm_sem);
+ rc = lmv_dir_striped(lli->lli_lsm_md);
+ up_read(&lli->lli_lsm_sem);
+
+ return rc;
}
static inline loff_t ll_file_maxbytes(struct inode *inode)
#define XATTR_ACL_DEFAULT_T 5
#define XATTR_LUSTRE_T 6
#define XATTR_OTHER_T 7
+#define XATTR_ENCRYPTION_T 9
ssize_t ll_listxattr(struct dentry *dentry, char *buffer, size_t size);
int ll_xattr_list(struct inode *inode, const char *name, int type,
*/
struct ll_digest_filename {
struct lu_fid ldf_fid;
- char ldf_excerpt[LLCRYPT_FNAME_DIGEST_SIZE];
+ char ldf_excerpt[LL_CRYPTO_BLOCK_SIZE];
};
int ll_setup_filename(struct inode *dir, const struct qstr *iname,
struct llcrypt_str *iname, struct llcrypt_str *oname,
struct lu_fid *fid);
int ll_revalidate_d_crypto(struct dentry *dentry, unsigned int flags);
+int ll_file_open_encrypt(struct inode *inode, struct file *filp);
+static inline char *xattr_for_enc(struct inode *inode)
+{
+ if (ll_sbi_has_name_encrypt(ll_i2sbi(inode)))
+ return LL_XATTR_NAME_ENCRYPTION_CONTEXT;
+
+ return LL_XATTR_NAME_ENCRYPTION_CONTEXT_OLD;
+}
#ifdef HAVE_LUSTRE_CRYPTO
extern const struct llcrypt_operations lustre_cryptops;
#endif