Whamcloud - gitweb
LU-812 ldiskfs: super_operations->dirty_inode now takes a flag
[fs/lustre-release.git] / lustre / osd-ldiskfs / osd_handler.c
index fcde844..e1bc36f 100644 (file)
@@ -53,8 +53,6 @@
 #include <linux/fs.h>
 /* XATTR_{REPLACE,CREATE} */
 #include <linux/xattr.h>
-/* simple_mkdir() */
-#include <lvfs.h>
 
 /*
  * struct OBD_{ALLOC,FREE}*()
@@ -623,12 +621,8 @@ static int osd_param_is_not_sane(const struct osd_device *dev,
 /*
  * Concurrency: shouldn't matter.
  */
-#ifdef HAVE_LDISKFS_JOURNAL_CALLBACK_ADD
 static void osd_trans_commit_cb(struct super_block *sb,
-                                struct journal_callback *jcb, int error)
-#else
-static void osd_trans_commit_cb(struct journal_callback *jcb, int error)
-#endif
+                                struct ldiskfs_journal_cb_entry *jcb, int error)
 {
         struct osd_thandle *oh = container_of0(jcb, struct osd_thandle, ot_jcb);
         struct thandle     *th  = &oh->ot_super;
@@ -825,7 +819,7 @@ static int osd_trans_stop(const struct lu_env *env, struct thandle *th)
                  * notice we don't do this in osd_trans_start()
                  * as underlying transaction can change during truncate
                  */
-                osd_journal_callback_set(hdl, osd_trans_commit_cb,
+                ldiskfs_journal_callback_add(hdl, osd_trans_commit_cb,
                                          &oh->ot_jcb);
 
                 LASSERT(oti->oti_txns == 1);
@@ -1079,14 +1073,31 @@ static int osd_commit_async(const struct lu_env *env,
 
 static int osd_ro(const struct lu_env *env, struct dt_device *d)
 {
-        struct super_block *sb = osd_sb(osd_dt_dev(d));
-        int rc;
-        ENTRY;
+       struct super_block *sb = osd_sb(osd_dt_dev(d));
+       struct block_device *dev = sb->s_bdev;
+#ifdef HAVE_DEV_SET_RDONLY
+       struct block_device *jdev = LDISKFS_SB(sb)->journal_bdev;
+       int rc = 0;
+#else
+       int rc = -EOPNOTSUPP;
+#endif
+       ENTRY;
 
+#ifdef HAVE_DEV_SET_RDONLY
        CERROR("*** setting %s read-only ***\n", osd_dt_dev(d)->od_svname);
 
-        rc = __lvfs_set_rdonly(sb->s_bdev, LDISKFS_SB(sb)->journal_bdev);
-        RETURN(rc);
+       if (jdev && (jdev != dev)) {
+               CDEBUG(D_IOCTL | D_HA, "set journal dev %lx rdonly\n",
+                      (long)jdev);
+               dev_set_rdonly(jdev);
+       }
+       CDEBUG(D_IOCTL | D_HA, "set dev %lx rdonly\n", (long)dev);
+       dev_set_rdonly(dev);
+#else
+       CERROR("%s: %lx CANNOT BE SET READONLY: rc = %d\n",
+              osd_dt_dev(d)->od_svname, (long)dev, rc);
+#endif
+       RETURN(rc);
 }
 
 /*
@@ -1363,7 +1374,8 @@ static void osd_inode_getattr(const struct lu_env *env,
 {
         attr->la_valid      |= LA_ATIME | LA_MTIME | LA_CTIME | LA_MODE |
                                LA_SIZE | LA_BLOCKS | LA_UID | LA_GID |
-                               LA_FLAGS | LA_NLINK | LA_RDEV | LA_BLKSIZE;
+                               LA_FLAGS | LA_NLINK | LA_RDEV | LA_BLKSIZE |
+                              LA_TYPE;
 
         attr->la_atime      = LTIME_S(inode->i_atime);
         attr->la_mtime      = LTIME_S(inode->i_mtime);
@@ -1665,7 +1677,7 @@ static int osd_attr_set(const struct lu_env *env,
        spin_unlock(&obj->oo_guard);
 
         if (!rc)
-                inode->i_sb->s_op->dirty_inode(inode);
+               ll_dirty_inode(inode, I_DIRTY_DATASYNC);
         return rc;
 }
 
@@ -1917,7 +1929,7 @@ static void osd_attr_init(struct osd_thread_info *info, struct osd_object *obj,
                  * enabled on ldiskfs (lquota takes care of it).
                  */
                 LASSERTF(result == 0, "%d", result);
-                inode->i_sb->s_op->dirty_inode(inode);
+               ll_dirty_inode(inode, I_DIRTY_DATASYNC);
         }
 
         attr->la_valid = valid;
@@ -1935,6 +1947,11 @@ static int __osd_object_create(struct osd_thread_info *info,
                                struct thandle *th)
 {
        int     result;
+       __u32   umask;
+
+       /* we drop umask so that permissions we pass are not affected */
+       umask = current->fs->umask;
+       current->fs->umask = 0;
 
        result = osd_create_type_f(dof->dof_type)(info, obj, attr, hint, dof,
                                                  th);
@@ -1946,7 +1963,10 @@ static int __osd_object_create(struct osd_thread_info *info,
                        unlock_new_inode(obj->oo_inode);
         }
 
-        return result;
+       /* restore previous umask value */
+       current->fs->umask = umask;
+
+       return result;
 }
 
 /**
@@ -1973,19 +1993,13 @@ int osd_fld_lookup(const struct lu_env *env, struct osd_device *osd,
        struct seq_server_site  *ss = osd_seq_site(osd);
        int                     rc;
 
-       if (fid_is_igif(fid)) {
-               range->lsr_flags = LU_SEQ_RANGE_MDT;
-               range->lsr_index = 0;
-               return 0;
-       }
-
        if (fid_is_idif(fid)) {
                range->lsr_flags = LU_SEQ_RANGE_OST;
                range->lsr_index = fid_idif_ost_idx(fid);
                return 0;
        }
 
-       if (!fid_is_norm(fid)) {
+       if (!fid_seq_in_fldb(fid_seq(fid))) {
                range->lsr_flags = LU_SEQ_RANGE_MDT;
                if (ss != NULL)
                        /* FIXME: If ss is NULL, it suppose not get lsr_index
@@ -2175,7 +2189,7 @@ static int osd_object_destroy(const struct lu_env *env,
                spin_lock(&obj->oo_guard);
                clear_nlink(inode);
                spin_unlock(&obj->oo_guard);
-               inode->i_sb->s_op->dirty_inode(inode);
+               ll_dirty_inode(inode, I_DIRTY_DATASYNC);
        }
 
        osd_trans_exec_op(env, th, OSD_OT_DESTROY);
@@ -2222,6 +2236,9 @@ int osd_ea_fid_set(struct osd_thread_info *info, struct inode *inode,
        if (OBD_FAIL_CHECK(OBD_FAIL_FID_INLMA))
                return 0;
 
+       if (OBD_FAIL_CHECK(OBD_FAIL_FID_IGIF) && fid_is_client_visible(fid))
+               return 0;
+
        lustre_lma_init(lma, fid);
        lustre_lma_swab(lma);
 
@@ -2473,7 +2490,7 @@ static int osd_object_ref_add(const struct lu_env *env,
        }
        LASSERT(inode->i_nlink <= LDISKFS_LINK_MAX);
        spin_unlock(&obj->oo_guard);
-       inode->i_sb->s_op->dirty_inode(inode);
+       ll_dirty_inode(inode, I_DIRTY_DATASYNC);
        LINVRNT(osd_invariant(obj));
 
        return 0;
@@ -2522,7 +2539,7 @@ static int osd_object_ref_del(const struct lu_env *env, struct dt_object *dt,
        if (S_ISDIR(inode->i_mode) && inode->i_nlink == 0)
                set_nlink(inode, 1);
        spin_unlock(&obj->oo_guard);
-       inode->i_sb->s_op->dirty_inode(inode);
+       ll_dirty_inode(inode, I_DIRTY_DATASYNC);
        LINVRNT(osd_invariant(obj));
 
        return 0;
@@ -2608,7 +2625,7 @@ static void osd_object_version_set(const struct lu_env *env,
         LDISKFS_I(inode)->i_fs_version = *new_version;
         /** Version is set after all inode operations are finished,
          *  so we should mark it dirty here */
-        inode->i_sb->s_op->dirty_inode(inode);
+       ll_dirty_inode(inode, I_DIRTY_DATASYNC);
 }
 
 /*
@@ -2622,6 +2639,7 @@ static int osd_xattr_set(const struct lu_env *env, struct dt_object *dt,
        struct inode           *inode    = obj->oo_inode;
        struct osd_thread_info *info     = osd_oti_get(env);
        int                     fs_flags = 0;
+       ENTRY;
 
         LASSERT(handle != NULL);
 
@@ -2818,9 +2836,13 @@ static int osd_object_sync(const struct lu_env *env, struct dt_object *dt)
        file->f_dentry = dentry;
        file->f_mapping = inode->i_mapping;
        file->f_op = inode->i_fop;
+#ifndef HAVE_FILE_FSYNC_4ARGS
        mutex_lock(&inode->i_mutex);
-       rc = file->f_op->fsync(file, dentry, 0);
+#endif
+       rc = do_fsync(file, 0);
+#ifndef HAVE_FILE_FSYNC_4ARGS
        mutex_unlock(&inode->i_mutex);
+#endif
        RETURN(rc);
 }
 
@@ -2959,7 +2981,8 @@ static int osd_index_try(const struct lu_env *env, struct dt_object *dt,
         }
         LINVRNT(osd_invariant(obj));
 
-       if (is_quota_glb_feat(feat))
+       if (result == 0 && is_quota_glb_feat(feat) &&
+           fid_seq(lu_object_fid(&dt->do_lu)) == FID_SEQ_QUOTA_GLB)
                result = osd_quota_migration(env, dt, feat);
 
         return result;
@@ -3163,7 +3186,8 @@ static int osd_remote_fid(const struct lu_env *env, struct osd_device *osd,
        int                     rc;
        ENTRY;
 
-       if ((!fid_is_norm(fid) && !fid_is_igif(fid)) || ss == NULL)
+       /* Those FID seqs, which are not in FLDB, must be local seq */
+       if (unlikely(!fid_seq_in_fldb(fid_seq(fid)) || ss == NULL))
                RETURN(0);
 
        rc = osd_fld_lookup(env, osd, fid, range);
@@ -4086,12 +4110,12 @@ osd_it_append_attrs(struct lu_dirent *ent, int len, __u16 type)
 {
        /* check if file type is required */
        if (ent->lde_attrs & LUDA_TYPE) {
-               int align = sizeof(struct luda_type) - 1;
                struct luda_type *lt;
+               int align = sizeof(*lt) - 1;
 
                len = (len + align) & ~align;
                lt = (struct luda_type *)(ent->lde_name + len);
-               lt->lt_type = cpu_to_le16(CFS_DTTOIF(type));
+               lt->lt_type = cpu_to_le16(DTTOIF(type));
        }
 
        ent->lde_attrs = cpu_to_le32(ent->lde_attrs);
@@ -4112,6 +4136,7 @@ osd_it_pack_dirent(struct lu_dirent *ent, struct lu_fid *fid, __u64 offset,
        ent->lde_reclen = cpu_to_le16(lu_dirent_calc_size(namelen, attr));
 
        strncpy(ent->lde_name, name, namelen);
+       ent->lde_name[namelen] = '\0';
        ent->lde_namelen = cpu_to_le16(namelen);
 
        /* append lustre attributes */
@@ -5013,12 +5038,14 @@ static void *osd_key_init(const struct lu_context *ctx,
 static void osd_key_fini(const struct lu_context *ctx,
                          struct lu_context_key *key, void* data)
 {
-        struct osd_thread_info *info = data;
+       struct osd_thread_info *info = data;
 
-        if (info->oti_hlock != NULL)
-                ldiskfs_htree_lock_free(info->oti_hlock);
-        OBD_FREE(info->oti_it_ea_buf, OSD_IT_EA_BUFSIZE);
-        OBD_FREE_PTR(info);
+       if (info->oti_hlock != NULL)
+               ldiskfs_htree_lock_free(info->oti_hlock);
+       OBD_FREE(info->oti_it_ea_buf, OSD_IT_EA_BUFSIZE);
+       lu_buf_free(&info->oti_iobuf.dr_pg_buf);
+       lu_buf_free(&info->oti_iobuf.dr_bl_buf);
+       OBD_FREE_PTR(info);
 }
 
 static void osd_key_exit(const struct lu_context *ctx,
@@ -5047,7 +5074,9 @@ static int osd_device_init(const struct lu_env *env, struct lu_device *d,
 {
        struct osd_device *osd = osd_dev(d);
 
-       strncpy(osd->od_svname, name, MAX_OBD_NAME);
+       if (strlcpy(osd->od_svname, name, sizeof(osd->od_svname))
+           >= sizeof(osd->od_svname))
+               return -E2BIG;
        return osd_procfs_init(osd, name);
 }
 
@@ -5137,13 +5166,15 @@ static int osd_mount(const struct lu_env *env,
                GOTO(out, rc);
        }
 
-       if (lvfs_check_rdonly(o->od_mnt->mnt_sb->s_bdev)) {
+#ifdef HAVE_DEV_SET_RDONLY
+       if (dev_check_rdonly(o->od_mnt->mnt_sb->s_bdev)) {
                CERROR("%s: underlying device %s is marked as read-only. "
                       "Setup failed\n", name, dev);
                mntput(o->od_mnt);
                o->od_mnt = NULL;
                GOTO(out, rc = -EROFS);
        }
+#endif
 
        if (!LDISKFS_HAS_COMPAT_FEATURE(o->od_mnt->mnt_sb,
            LDISKFS_FEATURE_COMPAT_HAS_JOURNAL)) {
@@ -5201,6 +5232,7 @@ static int osd_device_init0(const struct lu_env *env,
        struct lu_device        *l = osd2lu_dev(o);
        struct osd_thread_info *info;
        int                     rc;
+       int                     cplen = 0;
 
        /* if the module was re-loaded, env can loose its keys */
        rc = lu_env_refill((struct lu_env *) env);
@@ -5234,8 +5266,12 @@ static int osd_device_init0(const struct lu_env *env,
        if (rc < 0)
                GOTO(out_mnt, rc);
 
-       strncpy(o->od_svname, lustre_cfg_string(cfg, 4),
-                       sizeof(o->od_svname) - 1);
+       cplen = strlcpy(o->od_svname, lustre_cfg_string(cfg, 4),
+                       sizeof(o->od_svname));
+       if (cplen >= sizeof(o->od_svname)) {
+               rc = -E2BIG;
+               GOTO(out_mnt, rc);
+       }
 
        rc = osd_obj_map_init(o);
        if (rc != 0)