Whamcloud - gitweb
LU-15171 osd-ldiskfs: xattr_sem locking is missing for dquot_transfer
[fs/lustre-release.git] / lustre / osd-ldiskfs / osd_internal.h
index 5752917..705d8b0 100644 (file)
@@ -27,7 +27,6 @@
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
  *
  * lustre/osd/osd_internal.h
  *
@@ -91,6 +90,9 @@ extern struct kmem_cache *dynlock_cachep;
 #define OSD_STATFS_RESERVED            (1ULL << 23) /* 8MB */
 #define OSD_STATFS_RESERVED_SHIFT      (7) /* reserve 0.78% of all space */
 
+/* Default extent bytes when declaring write commit */
+#define OSD_DEFAULT_EXTENT_BYTES       (1U << 20)
+
 /* check if ldiskfs support project quota */
 #ifndef LDISKFS_IOC_FSSETXATTR
 #undef HAVE_PROJECT_QUOTA
@@ -153,6 +155,7 @@ struct osd_object {
 
        struct list_head        oo_xattr_list;
        struct lu_object_header *oo_header;
+       __u64                   oo_dirent_count;
 };
 
 struct osd_obj_seq {
@@ -239,11 +242,14 @@ struct osd_obj_orphan {
 };
 
 enum osd_t10_type {
-       OSD_T10_TYPE_UNKNOWN = 0,
-       OSD_T10_TYPE1_CRC,
-       OSD_T10_TYPE3_CRC,
-       OSD_T10_TYPE1_IP,
-       OSD_T10_TYPE3_IP
+       OSD_T10_TYPE_UNKNOWN    = 0,
+       OSD_T10_TYPE1           = 0x1,
+       OSD_T10_TYPE3           = 0x2,
+       OSD_T10_TYPE_CRC        = 0x4,
+       OSD_T10_TYPE1_CRC       = OSD_T10_TYPE1 | OSD_T10_TYPE_CRC,
+       OSD_T10_TYPE3_CRC       = OSD_T10_TYPE3 | OSD_T10_TYPE_CRC,
+       OSD_T10_TYPE1_IP        = OSD_T10_TYPE1,
+       OSD_T10_TYPE3_IP        = OSD_T10_TYPE3,
 };
 
 /*
@@ -269,9 +275,11 @@ struct osd_device {
                                  od_in_init:1,
                                  od_index_in_idif:1,
        /* Other flags */
+                                 od_read_cache:1,
+                                 od_writethrough_cache:1,
                                  od_nonrotational:1;
 
-       __s64                     od_auto_scrub_interval;
+
        __u32                     od_dirent_journal;
        int                       od_index;
        struct proc_dir_entry    *od_proc_entry;
@@ -279,6 +287,7 @@ struct osd_device {
 
        spinlock_t                od_osfs_lock;
 
+       int                       od_fallocate_zero_blocks;
        int                       od_connects;
        struct lu_site            od_site;
 
@@ -297,9 +306,6 @@ struct osd_device {
         * served bypassing pagecache unless already cached */
        unsigned long           od_writethrough_max_iosize;
 
-       int                     od_read_cache;
-       int                     od_writethrough_cache;
-
        struct brw_stats        od_brw_stats;
        atomic_t                od_r_in_flight;
        atomic_t                od_w_in_flight;
@@ -342,6 +348,9 @@ struct osd_device {
        int                      od_index_backup_stop;
        /* T10PI type, zero if not supported  */
        enum osd_t10_type        od_t10_type;
+       atomic_t                 od_commit_cb_in_flight;
+       wait_queue_head_t        od_commit_cb_done;
+       unsigned int __percpu   *od_extent_bytes_percpu;
 };
 
 static inline struct qsd_instance *osd_def_qsd(struct osd_device *osd)
@@ -380,24 +389,29 @@ enum osd_full_scrub_ratio {
 
 enum osd_op_type {
        OSD_OT_ATTR_SET         = 0,
-       OSD_OT_PUNCH            = 1,
-       OSD_OT_XATTR_SET        = 2,
-       OSD_OT_CREATE           = 3,
-       OSD_OT_DESTROY          = 4,
-       OSD_OT_REF_ADD          = 5,
-       OSD_OT_REF_DEL          = 6,
-       OSD_OT_WRITE            = 7,
-       OSD_OT_INSERT           = 8,
-       OSD_OT_DELETE           = 9,
-       OSD_OT_QUOTA            = 10,
-       OSD_OT_MAX              = 11
+       OSD_OT_PUNCH,
+       OSD_OT_XATTR_SET,
+       OSD_OT_CREATE,
+       OSD_OT_DESTROY,
+       OSD_OT_REF_ADD,
+       OSD_OT_REF_DEL,
+       OSD_OT_WRITE,
+       OSD_OT_INSERT,
+       OSD_OT_DELETE,
+       OSD_OT_QUOTA,
+       OSD_OT_PREALLOC,
+       OSD_OT_MAX
 };
 
 struct osd_access_lock {
        struct list_head         tl_list;
        struct osd_object       *tl_obj;
+       loff_t                   tl_start;
+       loff_t                   tl_end;
+       int                      tl_mode;
        bool                     tl_shared;
        bool                     tl_truncate;
+       bool                     tl_punch;
 };
 
 struct osd_thandle {
@@ -409,6 +423,7 @@ struct osd_thandle {
        /* Link to the device, for debugging. */
        struct lu_ref_link      ot_dev_link;
        unsigned int            ot_credits;
+       unsigned int            oh_declared_ext;
 
        /* quota IDs related to the transaction */
        unsigned short          ot_id_cnt;
@@ -572,12 +587,12 @@ struct osd_iobuf {
 
 int osd_security_file_alloc(struct file *file);
 
+#define osd_dirty_inode(inode, flag)  (inode)->i_sb->s_op->dirty_inode((inode), flag)
+
 #ifdef HAVE_INODE_TIMESPEC64
 # define osd_timespec                  timespec64
-# define osd_timespec_trunc(ts, gran)  timespec64_trunc((ts), (gran))
 #else
 # define osd_timespec                  timespec
-# define osd_timespec_trunc(ts, gran)  timespec_trunc((ts), (gran))
 #endif
 
 static inline struct osd_timespec osd_inode_time(struct inode *inode,
@@ -585,7 +600,7 @@ static inline struct osd_timespec osd_inode_time(struct inode *inode,
 {
        struct osd_timespec ts = { .tv_sec = seconds };
 
-       return osd_timespec_trunc(ts, inode->i_sb->s_time_gran);
+       return ts;
 }
 
 #define OSD_INS_CACHE_SIZE     8
@@ -698,32 +713,20 @@ struct osd_thread_info {
 
        struct page             **oti_dio_pages;
        int                     oti_dio_pages_used;
+
+       struct osd_it_ea_dirent *oti_seq_dirent;
+       struct osd_it_ea_dirent *oti_dir_dirent;
 };
 
 extern int ldiskfs_pdo;
 
+/* autoconf test is in lustre-build-ldiskfs.m4 */
 #ifdef HAVE_BVEC_ITER_ALL
 #define DECLARE_BVEC_ITER_ALL(iter) struct bvec_iter_all iter
 #else
 #define DECLARE_BVEC_ITER_ALL(iter) int iter
 #endif
 
-#ifndef HAVE_VFS_SETXATTR
-#define osd_setxattr(dentry, inode, name, buf, len, flag) \
-               ((inode)->i_op->setxattr(dentry, name, buf, len, flag))
-#define osd_getxattr(dentry, inode, name, buf, len) \
-               ((inode)->i_op->getxattr(dentry, name, buf, len))
-#define osd_removexattr(dentry, inode, name) \
-               ((inode)->i_op->removexattr(dentry, name))
-#else /* HAVE_VFS_SETXATTR */
-#define osd_setxattr(dentry, inode, name, buf, len, flag) \
-               __vfs_setxattr(dentry, inode, name, buf, len, flag)
-#define osd_getxattr(dentry, inode, name, buf, len) \
-               __vfs_getxattr(dentry, inode, name, buf, len)
-#define osd_removexattr(dentry, inode, name) \
-               __vfs_removexattr(dentry, name)
-#endif /* !HAVE_VFS_SETXATTR */
-
 static inline int __osd_xattr_get(struct inode *inode, struct dentry *dentry,
                                  const char *name, void *buf, int len)
 {
@@ -732,7 +735,7 @@ static inline int __osd_xattr_get(struct inode *inode, struct dentry *dentry,
 
        dentry->d_inode = inode;
        dentry->d_sb = inode->i_sb;
-       return osd_getxattr(dentry, inode, name, buf, len);
+       return ll_vfs_getxattr(dentry, inode, name, buf, len);
 }
 
 static inline int __osd_xattr_set(struct osd_thread_info *info,
@@ -744,7 +747,18 @@ static inline int __osd_xattr_set(struct osd_thread_info *info,
        dquot_initialize(inode);
        dentry->d_inode = inode;
        dentry->d_sb = inode->i_sb;
-       return osd_setxattr(dentry, inode, name, buf, buflen, fl);
+       return ll_vfs_setxattr(dentry, inode, name, buf, buflen, fl);
+}
+
+static inline char *osd_oid_name(char *name, size_t name_size,
+                                const struct lu_fid *fid, u64 id)
+{
+       snprintf(name, name_size,
+                (fid_seq_is_rsvd(fid_seq(fid)) ||
+                 fid_seq_is_mdt0(fid_seq(fid)) ||
+                 fid_seq_is_idif(fid_seq(fid))) ? "%llu" : "%llx", id);
+
+       return name;
 }
 
 #ifdef CONFIG_PROC_FS
@@ -767,12 +781,19 @@ osd_iget_fid(struct osd_thread_info *info, struct osd_device *dev,
             struct osd_inode_id *id, struct lu_fid *fid);
 int osd_ea_fid_set(struct osd_thread_info *info, struct inode *inode,
                   const struct lu_fid *fid, __u32 compat, __u32 incompat);
+struct osd_obj_seq *osd_seq_load(struct osd_thread_info *info,
+                                struct osd_device *osd, u64 seq);
 int osd_get_lma(struct osd_thread_info *info, struct inode *inode,
                struct dentry *dentry, struct lustre_ost_attrs *loa);
 void osd_add_oi_cache(struct osd_thread_info *info, struct osd_device *osd,
                      struct osd_inode_id *id, const struct lu_fid *fid);
 int osd_get_idif(struct osd_thread_info *info, struct inode *inode,
                 struct dentry *dentry, struct lu_fid *fid);
+struct osd_it_ea *osd_it_dir_init(const struct lu_env *env, struct inode *inode,
+                                 __u32 attr);
+void osd_it_dir_fini(const struct lu_env *env, struct osd_it_ea *oie,
+                    struct inode *inode);
+int osd_ldiskfs_it_fill(const struct lu_env *env, const struct dt_it *di);
 
 int osd_obj_map_init(const struct lu_env *env, struct osd_device *osd);
 void osd_obj_map_fini(struct osd_device *dev);
@@ -798,15 +819,19 @@ int osd_obj_spec_insert(struct osd_thread_info *info, struct osd_device *osd,
 int osd_obj_spec_update(struct osd_thread_info *info, struct osd_device *osd,
                        const struct lu_fid *fid, const struct osd_inode_id *id,
                        handle_t *th);
+int osd_obj_del_entry(struct osd_thread_info *info, struct osd_device *osd,
+                     struct dentry *dird, char *name, int namelen,
+                     handle_t *th);
 
 char *osd_lf_fid2name(const struct lu_fid *fid);
 int osd_scrub_start(const struct lu_env *env, struct osd_device *dev,
                    __u32 flags);
 void osd_scrub_stop(struct osd_device *dev);
-int osd_scrub_setup(const struct lu_env *env, struct osd_device *dev);
+int osd_scrub_setup(const struct lu_env *env, struct osd_device *dev,
+                   bool restored);
 void osd_scrub_cleanup(const struct lu_env *env, struct osd_device *dev);
-int osd_oii_insert(struct osd_device *dev, struct osd_idmap_cache *oic,
-                  int insert);
+int osd_oii_insert(struct osd_device *dev, const struct lu_fid *fid,
+                  struct osd_inode_id *id, int insert);
 int osd_oii_lookup(struct osd_device *dev, const struct lu_fid *fid,
                   struct osd_inode_id *id);
 void osd_scrub_dump(struct seq_file *m, struct osd_device *dev);
@@ -833,6 +858,13 @@ int osd_lookup_in_remote_parent(struct osd_thread_info *oti,
 
 int osd_ost_seq_exists(struct osd_thread_info *info, struct osd_device *osd,
                       __u64 seq);
+int osd_scrub_refresh_mapping(struct osd_thread_info *info,
+                             struct osd_device *dev,
+                             const struct lu_fid *fid,
+                             const struct osd_inode_id *id,
+                             int ops, bool force,
+                             enum oi_check_flags flags, bool *exist);
+
 /* osd_quota_fmt.c */
 int walk_tree_dqentry(const struct lu_env *env, struct osd_object *obj,
                       int type, uint blk, int depth, uint index,
@@ -1022,14 +1054,14 @@ static inline int lu_device_is_osd(const struct lu_device *d)
 
 static inline struct osd_device *osd_dt_dev(const struct dt_device *d)
 {
-        LASSERT(lu_device_is_osd(&d->dd_lu_dev));
-        return container_of0(d, struct osd_device, od_dt_dev);
+       LASSERT(lu_device_is_osd(&d->dd_lu_dev));
+       return container_of(d, struct osd_device, od_dt_dev);
 }
 
 static inline struct osd_device *osd_dev(const struct lu_device *d)
 {
-        LASSERT(lu_device_is_osd(d));
-        return osd_dt_dev(container_of0(d, struct dt_device, dd_lu_dev));
+       LASSERT(lu_device_is_osd(d));
+       return osd_dt_dev(container_of(d, struct dt_device, dd_lu_dev));
 }
 
 static inline struct osd_device *osd_obj2dev(const struct osd_object *o)
@@ -1042,14 +1074,22 @@ static inline struct super_block *osd_sb(const struct osd_device *dev)
        return dev->od_mnt->mnt_sb;
 }
 
+static inline const char *osd_sb2name(const struct super_block *sb)
+{
+       /* this is LDISKFS_SB(sb), but preserves "const" */
+       const struct ldiskfs_sb_info *sbi = sb->s_fs_info;
+
+       return sbi->s_es->s_volume_name;
+}
+
 static inline const char *osd_dev2name(const struct osd_device *dev)
 {
-       return osd_sb(dev)->s_id;
+       return osd_sb2name(osd_sb(dev));
 }
 
 static inline const char *osd_ino2name(const struct inode *inode)
 {
-       return inode->i_sb->s_id;
+       return osd_sb2name(inode->i_sb);
 }
 
 /**
@@ -1065,13 +1105,13 @@ static inline void osd_object_put(const struct lu_env *env,
 
 static inline int osd_object_is_root(const struct osd_object *obj)
 {
-        return osd_sb(osd_obj2dev(obj))->s_root->d_inode == obj->oo_inode;
+       return obj->oo_inode && is_root_inode(obj->oo_inode);
 }
 
 static inline struct osd_object *osd_obj(const struct lu_object *o)
 {
-        LASSERT(lu_device_is_osd(o->lo_dev));
-        return container_of0(o, struct osd_object, oo_dt.do_lu);
+       LASSERT(lu_device_is_osd(o->lo_dev));
+       return container_of(o, struct osd_object, oo_dt.do_lu);
 }
 
 static inline struct osd_object *osd_dt_obj(const struct dt_object *d)
@@ -1166,6 +1206,43 @@ struct dentry *osd_child_dentry_by_inode(const struct lu_env *env,
         return child_dentry;
 }
 
+/* build quasi file structure when it is needed to call an inode i_fop */
+static inline struct file *osd_quasi_file_init(const struct lu_env *env,
+                                              struct dentry *dentry,
+                                              struct inode *inode)
+{
+       struct osd_thread_info *info = osd_oti_get(env);
+
+       info->oti_file.f_path.dentry = dentry;
+       info->oti_file.f_mapping = inode->i_mapping;
+       info->oti_file.f_op = inode->i_fop;
+       info->oti_file.f_inode = inode;
+       info->oti_file.f_pos = 0;
+       info->oti_file.private_data = NULL;
+       info->oti_file.f_cred = current_cred();
+       info->oti_file.f_flags = O_NOATIME;
+       info->oti_file.f_mode = FMODE_64BITHASH | FMODE_NONOTIFY;
+
+       return &info->oti_file;
+}
+
+static inline struct file *osd_quasi_file(const struct lu_env *env,
+                                         struct inode *inode)
+{
+       struct osd_thread_info *info = osd_oti_get(env);
+
+       info->oti_obj_dentry.d_inode = inode;
+       info->oti_obj_dentry.d_sb = inode->i_sb;
+
+       return osd_quasi_file_init(env, &info->oti_obj_dentry, inode);
+}
+
+static inline struct file *osd_quasi_file_by_dentry(const struct lu_env *env,
+                                                   struct dentry *dentry)
+{
+       return osd_quasi_file_init(env, dentry, dentry->d_inode);
+}
+
 extern int osd_trans_declare_op2rb[];
 extern int ldiskfs_track_declares_assert;
 void osd_trans_dump_creds(const struct lu_env *env, struct thandle *th);
@@ -1192,6 +1269,11 @@ static inline void osd_trans_declare_op(const struct lu_env *env,
        oh->ot_credits += credits;
 }
 
+/* linux: v5.4-rc3-21-g933f1c1e0b75 renamed h_buffer_credits */
+#ifdef HAVE_JOURNAL_TOTAL_CREDITS
+#define h_buffer_credits h_total_credits
+#endif
+
 static inline void osd_trans_exec_op(const struct lu_env *env,
                                     struct thandle *th,
                                     enum osd_op_type op)
@@ -1469,6 +1551,12 @@ osd_index_backup(const struct lu_env *env, struct osd_device *osd, bool backup)
 # define ldiskfs_has_feature_dirdata(sb) \
        LDISKFS_HAS_INCOMPAT_FEATURE(sb, LDISKFS_FEATURE_INCOMPAT_DIRDATA)
 # endif
+# ifdef LDISKFS_FEATURE_INCOMPAT_LARGEDIR
+# define ldiskfs_has_feature_largedir(sb) \
+       LDISKFS_HAS_INCOMPAT_FEATURE(sb, LDISKFS_FEATURE_INCOMPAT_LARGEDIR)
+# define ldiskfs_set_feature_largedir(sb) \
+       LDISKFS_SET_INCOMPAT_FEATURE(sb, LDISKFS_FEATURE_INCOMPAT_LARGEDIR)
+# endif
 # ifdef LDISKFS_FEATURE_COMPAT_HAS_JOURNAL
 # define ldiskfs_has_feature_journal(sb) \
        LDISKFS_HAS_COMPAT_FEATURE(sb, LDISKFS_FEATURE_COMPAT_HAS_JOURNAL)
@@ -1486,8 +1574,8 @@ osd_index_backup(const struct lu_env *env, struct osd_device *osd, bool backup)
 
 int osd_trunc_lock(struct osd_object *obj, struct osd_thandle *oh,
                   bool shared);
-void osd_trunc_unlock_all(struct list_head *list);
-void osd_process_truncates(struct list_head *list);
+void osd_trunc_unlock_all(const struct lu_env *env, struct list_head *list);
+void osd_process_truncates(const struct lu_env *env, struct list_head *list);
 void osd_execute_truncate(struct osd_object *obj);
 
 #ifdef HAVE_BIO_ENDIO_USES_ONE_ARG
@@ -1553,4 +1641,12 @@ static inline bool bio_integrity_prep_fn(struct bio *bio,
 #define osd_bio_nr_segs(bio)           bio_segments((bio))
 #endif /* HAVE_BIO_BI_PHYS_SEGMENTS */
 
+#ifdef HAVE_GET_INODE_USAGE
+#define lock_dquot_transfer(inode) down_read(&LDISKFS_I(inode)->xattr_sem)
+#define unlock_dquot_transfer(inode) up_read(&LDISKFS_I(inode)->xattr_sem)
+#else
+#define lock_dquot_transfer(inode) do {} while (0)
+#define unlock_dquot_transfer(inode) do {} while (0)
+#endif
+
 #endif /* _OSD_INTERNAL_H */