* Top-level entry points into osd module
*
* Author: Nikita Danilov <nikita@clusterfs.com>
+ * Pravin Shelar <pravin.shelar@sun.com> : Added fid in dirent
*/
#ifndef EXPORT_SYMTAB
/**
* to protect index ops.
*/
- struct rw_semaphore oo_ext_idx_sem;
- struct rw_semaphore oo_sem;
+ cfs_rw_semaphore_t oo_ext_idx_sem;
+ cfs_rw_semaphore_t oo_sem;
struct osd_directory *oo_dir;
/** protects inode attributes. */
- spinlock_t oo_guard;
+ cfs_spinlock_t oo_guard;
/**
* Following two members are used to indicate the presence of dot and
* dotdot in the given directory. This is required for interop mode
* (b11826).
*/
- int oo_compat_dot_created;
- int oo_compat_dotdot_created;
+ int oo_compat_dot_created;
+ int oo_compat_dotdot_created;
const struct lu_env *oo_owner;
#ifdef CONFIG_LOCKDEP
mo->oo_dt.do_ops = &osd_obj_ops;
l->lo_ops = &osd_lu_obj_ops;
- init_rwsem(&mo->oo_sem);
- init_rwsem(&mo->oo_ext_idx_sem);
- spin_lock_init(&mo->oo_guard);
+ cfs_init_rwsem(&mo->oo_sem);
+ cfs_init_rwsem(&mo->oo_ext_idx_sem);
+ cfs_spin_lock_init(&mo->oo_guard);
return l;
} else
return NULL;
LASSERT(!lu_object_is_dying(l->lo_header));
if (o->oo_inode != NULL && osd_inode_unlinked(o->oo_inode))
- set_bit(LU_OBJECT_HEARD_BANSHEE, &l->lo_header->loh_flags);
+ cfs_set_bit(LU_OBJECT_HEARD_BANSHEE, &l->lo_header->loh_flags);
}
/*
* Concurrency: shouldn't matter.
*/
int osd_statfs(const struct lu_env *env, struct dt_device *d,
- struct kstatfs *sfs)
+ cfs_kstatfs_t *sfs)
{
struct osd_device *osd = osd_dt_dev(d);
struct super_block *sb = osd_sb(osd);
int result = 0;
- spin_lock(&osd->od_osfs_lock);
+ cfs_spin_lock(&osd->od_osfs_lock);
/* cache 1 second */
if (cfs_time_before_64(osd->od_osfs_age, cfs_time_shift_64(-1))) {
result = ll_do_statfs(sb, &osd->od_kstatfs);
if (likely(result == 0))
*sfs = osd->od_kstatfs;
- spin_unlock(&osd->od_osfs_lock);
+ cfs_spin_unlock(&osd->od_osfs_lock);
return result;
}
LINVRNT(osd_invariant(obj));
LASSERT(obj->oo_owner != env);
- down_read_nested(&obj->oo_sem, role);
+ cfs_down_read_nested(&obj->oo_sem, role);
LASSERT(obj->oo_owner == NULL);
oti->oti_r_locks++;
LINVRNT(osd_invariant(obj));
LASSERT(obj->oo_owner != env);
- down_write_nested(&obj->oo_sem, role);
+ cfs_down_write_nested(&obj->oo_sem, role);
LASSERT(obj->oo_owner == NULL);
obj->oo_owner = env;
LASSERT(oti->oti_r_locks > 0);
oti->oti_r_locks--;
- up_read(&obj->oo_sem);
+ cfs_up_read(&obj->oo_sem);
}
static void osd_object_write_unlock(const struct lu_env *env,
LASSERT(oti->oti_w_locks > 0);
oti->oti_w_locks--;
obj->oo_owner = NULL;
- up_write(&obj->oo_sem);
+ cfs_up_write(&obj->oo_sem);
}
static int osd_object_write_locked(const struct lu_env *env,
RETURN(-ESTALE);
}
- spin_lock(&capa_lock);
+ cfs_spin_lock(&capa_lock);
for (i = 0; i < 2; i++) {
if (keys[i].lk_keyid == capa->lc_keyid) {
oti->oti_capa_key = keys[i];
break;
}
}
- spin_unlock(&capa_lock);
+ cfs_spin_unlock(&capa_lock);
if (i == 2) {
DEBUG_CAPA(D_ERROR, capa, "no matched capa key");
if (osd_object_auth(env, dt, capa, CAPA_OPC_META_READ))
return -EACCES;
- spin_lock(&obj->oo_guard);
+ cfs_spin_lock(&obj->oo_guard);
osd_inode_getattr(env, obj->oo_inode, attr);
- spin_unlock(&obj->oo_guard);
+ cfs_spin_unlock(&obj->oo_guard);
return 0;
}
i_size_write(inode, attr->la_size);
}
+#if 0
/* OSD should not change "i_blocks" which is used by quota.
- * "i_blocks" should be changed by ldiskfs only.
- * Enable this assignment for SOM purpose now, until it is
- * stored in SOM EA. */
+ * "i_blocks" should be changed by ldiskfs only. */
if (bits & LA_BLOCKS)
inode->i_blocks = attr->la_blocks;
-
+#endif
if (bits & LA_MODE)
inode->i_mode = (inode->i_mode & S_IFMT) |
(attr->la_mode & ~S_IFMT);
if (bits & LA_RDEV)
inode->i_rdev = attr->la_rdev;
- if (bits & LA_FLAGS) {
- struct ldiskfs_inode_info *li = LDISKFS_I(inode);
-
- li->i_flags = (li->i_flags & ~LDISKFS_FL_USER_MODIFIABLE) |
- (attr->la_flags & LDISKFS_FL_USER_MODIFIABLE);
- }
+ if (bits & LA_FLAGS)
+ inode->i_flags = ll_ext_to_inode_flags(attr->la_flags);
return 0;
}
if (osd_object_auth(env, dt, capa, CAPA_OPC_META_WRITE))
return -EACCES;
- spin_lock(&obj->oo_guard);
+ cfs_spin_lock(&obj->oo_guard);
rc = osd_inode_setattr(env, obj->oo_inode, attr);
- spin_unlock(&obj->oo_guard);
+ cfs_spin_unlock(&obj->oo_guard);
if (!rc)
mark_inode_dirty(obj->oo_inode);
static int osd_mkfile(struct osd_thread_info *info, struct osd_object *obj,
- umode_t mode,
+ cfs_umode_t mode,
struct dt_allocation_hint *hint,
struct thandle *th)
{
struct dt_object_format *dof,
struct thandle *th)
{
- umode_t mode = attr->la_mode & (S_IFMT | S_IRWXUGO | S_ISVTX);
+ cfs_umode_t mode = attr->la_mode & (S_IFMT | S_IRWXUGO | S_ISVTX);
int result;
LINVRNT(osd_invariant(obj));
static void osd_ah_init(const struct lu_env *env, struct dt_allocation_hint *ah,
- struct dt_object *parent, umode_t child_mode)
+ struct dt_object *parent, cfs_umode_t child_mode)
{
LASSERT(ah);
rc = inode->i_op->setxattr(dentry, name, buf->lb_buf,
buf->lb_len, fs_flags);
/* ctime should not be updated with server-side time. */
- spin_lock(&obj->oo_guard);
+ cfs_spin_lock(&obj->oo_guard);
inode->i_ctime = *t;
- spin_unlock(&obj->oo_guard);
+ cfs_spin_unlock(&obj->oo_guard);
mark_inode_dirty(inode);
return rc;
}
}
/**
- * Helper function to pack the fid
+ * Helper function to pack the fid, ldiskfs stores fid in packed format.
*/
void osd_fid_pack(struct osd_fid_pack *pack, const struct dt_rec *fid,
struct lu_fid *befider)
pack->fp_len = sizeof(*befider) + 1;
}
+/**
+ * ldiskfs supports fid in dirent, it is passed in dentry->d_fsdata.
+ * lustre 1.8 also uses d_fsdata for passing other info to ldiskfs.
+ * To have compatilibility with 1.8 ldiskfs driver we need to have
+ * magic number at start of fid data.
+ * \ldiskfs_dentry_param is used only to pass fid from osd to ldiskfs.
+ * its inmemory API.
+ */
+void osd_get_ldiskfs_dirent_param(struct ldiskfs_dentry_param *param,
+ const struct dt_rec *fid)
+{
+ param->edp_magic = LDISKFS_LUFID_MAGIC;
+ param->edp_len = sizeof(struct lu_fid) + 1;
+
+ fid_cpu_to_be((struct lu_fid *)param->edp_data,
+ (struct lu_fid *)fid);
+}
+
int osd_fid_unpack(struct lu_fid *fid, const struct osd_fid_pack *pack)
{
int result;
if (rc > 0) {
lustre_lma_swab(mdt_attrs);
- memcpy(fid, &mdt_attrs->lma_self_fid, sizeof(*mdt_attrs));
+ memcpy(fid, &mdt_attrs->lma_self_fid, sizeof(*fid));
rc = 0;
} else if (rc == -ENODATA) {
osd_igif_get(env, inode, fid);
rc = 0;
}
iput(inode);
-
out:
RETURN(rc);
}
struct osd_object *obj = osd_dt_obj(dt);
struct osd_thread_info *info = osd_oti_get(env);
int result;
- int is_root = 0;
ENTRY;
result = __osd_object_create(info, obj, attr, hint, dof, th);
- if (hint && hint->dah_parent)
- is_root = osd_object_is_root(osd_dt_obj(hint->dah_parent));
-
/* objects under osd root shld have igif fid, so dont add fid EA */
- if (result == 0 && is_root == 0)
+ if (result == 0 && fid_seq(fid) >= FID_SEQ_DISTRIBUTED_START)
result = osd_ea_fid_set(env, dt, fid);
if (result == 0)
LASSERT(osd_write_locked(env, obj));
LASSERT(th != NULL);
- spin_lock(&obj->oo_guard);
+ cfs_spin_lock(&obj->oo_guard);
LASSERT(inode->i_nlink < LDISKFS_LINK_MAX);
inode->i_nlink++;
- spin_unlock(&obj->oo_guard);
+ cfs_spin_unlock(&obj->oo_guard);
mark_inode_dirty(inode);
LINVRNT(osd_invariant(obj));
}
LASSERT(osd_write_locked(env, obj));
LASSERT(th != NULL);
- spin_lock(&obj->oo_guard);
+ cfs_spin_lock(&obj->oo_guard);
LASSERT(inode->i_nlink > 0);
inode->i_nlink--;
- spin_unlock(&obj->oo_guard);
+ cfs_spin_unlock(&obj->oo_guard);
mark_inode_dirty(inode);
LINVRNT(osd_invariant(obj));
}
*t = inode->i_ctime;
rc = inode->i_op->removexattr(dentry, name);
/* ctime should not be updated with server-side time. */
- spin_lock(&obj->oo_guard);
+ cfs_spin_lock(&obj->oo_guard);
inode->i_ctime = *t;
- spin_unlock(&obj->oo_guard);
+ cfs_spin_unlock(&obj->oo_guard);
mark_inode_dirty(inode);
return rc;
}
__u32 d[4], s[4];
s[0] = obj->oo_inode->i_uid;
- get_random_bytes(&(s[1]), sizeof(__u32));
+ ll_get_random_bytes(&(s[1]), sizeof(__u32));
s[2] = obj->oo_inode->i_gid;
- get_random_bytes(&(s[3]), sizeof(__u32));
+ ll_get_random_bytes(&(s[3]), sizeof(__u32));
rc = capa_encrypt_id(d, s, key->lk_key, CAPA_HMAC_KEY_MAX_LEN);
if (unlikely(rc))
RETURN(ERR_PTR(rc));
RETURN(oc);
}
- spin_lock(&capa_lock);
+ cfs_spin_lock(&capa_lock);
*key = dev->od_capa_keys[1];
- spin_unlock(&capa_lock);
+ cfs_spin_unlock(&capa_lock);
capa->lc_keyid = key->lk_keyid;
capa->lc_expiry = cfs_time_current_sec() + dev->od_capa_timeout;
OBD_ALLOC_PTR(dir);
if (dir != NULL) {
- spin_lock(&obj->oo_guard);
+ cfs_spin_lock(&obj->oo_guard);
if (obj->oo_dir == NULL)
obj->oo_dir = dir;
else
* Concurrent thread allocated container data.
*/
OBD_FREE_PTR(dir);
- spin_unlock(&obj->oo_guard);
+ cfs_spin_unlock(&obj->oo_guard);
/*
* Now, that we have container data, serialize its
* initialization.
*/
- down_write(&obj->oo_ext_idx_sem);
+ cfs_down_write(&obj->oo_ext_idx_sem);
/*
* recheck under lock.
*/
result = osd_iam_container_init(env, obj, dir);
else
result = 0;
- up_write(&obj->oo_ext_idx_sem);
+ cfs_up_write(&obj->oo_ext_idx_sem);
} else
result = -ENOMEM;
} else
*
* which doesn't work for globally shared files like /last-received.
*/
-int fsfilt_ldiskfs_read(struct inode *inode, void *buf, int size, loff_t *offs);
-int fsfilt_ldiskfs_write_handle(struct inode *inode, void *buf, int bufsize,
- loff_t *offs, handle_t *handle);
+static int osd_ldiskfs_readlink(struct inode *inode, char *buffer, int buflen)
+{
+ struct ldiskfs_inode_info *ei = LDISKFS_I(inode);
+
+ memcpy(buffer, (char*)ei->i_data, buflen);
+
+ return buflen;
+}
+
+static int osd_ldiskfs_read(struct inode *inode, void *buf, int size,
+ loff_t *offs)
+{
+ struct buffer_head *bh;
+ unsigned long block;
+ int osize = size;
+ int blocksize;
+ int csize;
+ int boffs;
+ int err;
+
+ /* prevent reading after eof */
+ spin_lock(&inode->i_lock);
+ if (i_size_read(inode) < *offs + size) {
+ size = i_size_read(inode) - *offs;
+ spin_unlock(&inode->i_lock);
+ if (size < 0) {
+ CDEBUG(D_EXT2, "size %llu is too short to read @%llu\n",
+ i_size_read(inode), *offs);
+ return -EBADR;
+ } else if (size == 0) {
+ return 0;
+ }
+ } else {
+ spin_unlock(&inode->i_lock);
+ }
+
+ blocksize = 1 << inode->i_blkbits;
+
+ while (size > 0) {
+ block = *offs >> inode->i_blkbits;
+ boffs = *offs & (blocksize - 1);
+ csize = min(blocksize - boffs, size);
+ bh = ldiskfs_bread(NULL, inode, block, 0, &err);
+ if (!bh) {
+ CERROR("can't read block: %d\n", err);
+ return err;
+ }
+
+ memcpy(buf, bh->b_data + boffs, csize);
+ brelse(bh);
+
+ *offs += csize;
+ buf += csize;
+ size -= csize;
+ }
+ return osize;
+}
static ssize_t osd_read(const struct lu_env *env, struct dt_object *dt,
struct lu_buf *buf, loff_t *pos,
struct lustre_capa *capa)
{
- struct inode *inode = osd_dt_obj(dt)->oo_inode;
+ struct osd_object *obj = osd_dt_obj(dt);
+ struct inode *inode = obj->oo_inode;
+ int rc;
if (osd_object_auth(env, dt, capa, CAPA_OPC_BODY_READ))
RETURN(-EACCES);
- return fsfilt_ldiskfs_read(inode, buf->lb_buf, buf->lb_len, pos);
+ /* Read small symlink from inode body as we need to maintain correct
+ * on-disk symlinks for ldiskfs.
+ */
+ if (S_ISLNK(obj->oo_dt.do_lu.lo_header->loh_attr) &&
+ (buf->lb_len <= sizeof (LDISKFS_I(inode)->i_data)))
+ rc = osd_ldiskfs_readlink(inode, buf->lb_buf, buf->lb_len);
+ else
+ rc = osd_ldiskfs_read(inode, buf->lb_buf, buf->lb_len, pos);
+
+ return rc;
+}
+
+static int osd_ldiskfs_writelink(struct inode *inode, char *buffer, int buflen)
+{
+
+ memcpy((char*)&LDISKFS_I(inode)->i_data, (char *)buffer,
+ buflen);
+ LDISKFS_I(inode)->i_disksize = buflen;
+ i_size_write(inode, buflen);
+ inode->i_sb->s_op->dirty_inode(inode);
+
+ return 0;
+}
+
+static int osd_ldiskfs_write_record(struct inode *inode, void *buf, int bufsize,
+ loff_t *offs, handle_t *handle)
+{
+ struct buffer_head *bh = NULL;
+ loff_t offset = *offs;
+ loff_t new_size = i_size_read(inode);
+ unsigned long block;
+ int blocksize = 1 << inode->i_blkbits;
+ int err = 0;
+ int size;
+ int boffs;
+
+ while (bufsize > 0) {
+ if (bh != NULL)
+ brelse(bh);
+
+ block = offset >> inode->i_blkbits;
+ boffs = offset & (blocksize - 1);
+ size = min(blocksize - boffs, bufsize);
+ bh = ldiskfs_bread(handle, inode, block, 1, &err);
+ if (!bh) {
+ CERROR("can't read/create block: %d\n", err);
+ break;
+ }
+
+ err = ldiskfs_journal_get_write_access(handle, bh);
+ if (err) {
+ CERROR("journal_get_write_access() returned error %d\n",
+ err);
+ break;
+ }
+ LASSERTF(boffs + size <= bh->b_size,
+ "boffs %d size %d bh->b_size %lu",
+ boffs, size, (unsigned long)bh->b_size);
+ memcpy(bh->b_data + boffs, buf, size);
+ err = ldiskfs_journal_dirty_metadata(handle, bh);
+ if (err)
+ break;
+
+ if (offset + size > new_size)
+ new_size = offset + size;
+ offset += size;
+ bufsize -= size;
+ buf += size;
+ }
+ if (bh)
+ brelse(bh);
+
+ /* correct in-core and on-disk sizes */
+ if (new_size > i_size_read(inode)) {
+ spin_lock(&inode->i_lock);
+ if (new_size > i_size_read(inode))
+ i_size_write(inode, new_size);
+ if (i_size_read(inode) > LDISKFS_I(inode)->i_disksize) {
+ LDISKFS_I(inode)->i_disksize = i_size_read(inode);
+ inode->i_sb->s_op->dirty_inode(inode);
+ }
+ spin_unlock(&inode->i_lock);
+ }
+
+ if (err == 0)
+ *offs = offset;
+ return err;
}
static ssize_t osd_write(const struct lu_env *env, struct dt_object *dt,
struct thandle *handle, struct lustre_capa *capa,
int ignore_quota)
{
- struct inode *inode = osd_dt_obj(dt)->oo_inode;
+ struct osd_object *obj = osd_dt_obj(dt);
+ struct inode *inode = obj->oo_inode;
struct osd_thandle *oh;
- ssize_t result;
+ ssize_t result = 0;
#ifdef HAVE_QUOTA_SUPPORT
cfs_cap_t save = current->cap_effective;
#endif
else
current->cap_effective &= ~CFS_CAP_SYS_RESOURCE_MASK;
#endif
- result = fsfilt_ldiskfs_write_handle(inode, buf->lb_buf, buf->lb_len,
- pos, oh->ot_handle);
+ /* Write small symlink to inode body as we need to maintain correct
+ * on-disk symlinks for ldiskfs.
+ */
+ if(S_ISLNK(obj->oo_dt.do_lu.lo_header->loh_attr) &&
+ (buf->lb_len < sizeof (LDISKFS_I(inode)->i_data)))
+ result = osd_ldiskfs_writelink(inode, buf->lb_buf, buf->lb_len);
+ else
+ result = osd_ldiskfs_write_record(inode, buf->lb_buf,
+ buf->lb_len, pos,
+ oh->ot_handle);
#ifdef HAVE_QUOTA_SUPPORT
current->cap_effective = save;
#endif
RETURN(rc);
}
+static inline int osd_get_fid_from_dentry(struct ldiskfs_dir_entry_2 *de,
+ struct dt_rec *fid)
+{
+ struct osd_fid_pack *rec;
+ int rc = -ENODATA;
+
+ if (de->file_type & LDISKFS_DIRENT_LUFID) {
+ rec = (struct osd_fid_pack *) (de->name + de->name_len + 1);
+ rc = osd_fid_unpack((struct lu_fid *)fid, rec);
+ }
+ RETURN(rc);
+}
+
/**
* Index delete function for interoperability mode (b11826).
* It will remove the directory entry added by osd_index_ea_insert().
dentry = osd_child_dentry_get(env, obj,
(char *)key, strlen((char *)key));
- down_write(&obj->oo_ext_idx_sem);
- bh = ldiskfs_find_entry(dentry, &de);
+ cfs_down_write(&obj->oo_ext_idx_sem);
+ bh = ll_ldiskfs_find_entry(dir, dentry, &de);
if (bh) {
struct osd_thread_info *oti = osd_oti_get(env);
struct timespec *ctime = &oti->oti_time;
rc = ldiskfs_delete_entry(oh->ot_handle,
dir, de, bh);
/* xtime should not be updated with server-side time. */
- spin_lock(&obj->oo_guard);
+ cfs_spin_lock(&obj->oo_guard);
dir->i_ctime = *ctime;
dir->i_mtime = *mtime;
- spin_unlock(&obj->oo_guard);
+ cfs_spin_unlock(&obj->oo_guard);
mark_inode_dirty(dir);
brelse(bh);
} else
rc = -ENOENT;
- up_write(&obj->oo_ext_idx_sem);
+ cfs_up_write(&obj->oo_ext_idx_sem);
LASSERT(osd_invariant(obj));
RETURN(rc);
}
rc = iam_it_get(it, (struct iam_key *)key);
if (rc >= 0) {
if (S_ISDIR(obj->oo_inode->i_mode))
- iam_rec = (struct iam_rec *)oti->oti_fid_packed;
+ iam_rec = (struct iam_rec *)oti->oti_ldp;
else
iam_rec = (struct iam_rec *) rec;
cfs_cap_t save = current->cap_effective;
#endif
struct osd_thread_info *oti = osd_oti_get(env);
- struct iam_rec *iam_rec = (struct iam_rec *)oti->oti_fid_packed;
+ struct iam_rec *iam_rec = (struct iam_rec *)oti->oti_ldp;
int rc;
ENTRY;
*/
static int __osd_ea_add_rec(struct osd_thread_info *info,
struct osd_object *pobj,
- struct osd_object *cobj,
+ struct inode *cinode,
const char *name,
+ const struct dt_rec *fid,
struct thandle *th)
{
+ struct ldiskfs_dentry_param *ldp;
struct dentry *child;
struct osd_thandle *oth;
- struct inode *cinode = cobj->oo_inode;
int rc;
oth = container_of(th, struct osd_thandle, ot_super);
LASSERT(oth->ot_handle->h_transaction != NULL);
child = osd_child_dentry_get(info->oti_env, pobj, name, strlen(name));
+
+ if (fid_is_igif((struct lu_fid *)fid) ||
+ fid_seq((struct lu_fid *)fid) >= FID_SEQ_DISTRIBUTED_START) {
+ ldp = (struct ldiskfs_dentry_param *)info->oti_ldp;
+ osd_get_ldiskfs_dirent_param(ldp, fid);
+ child->d_fsdata = (void*) ldp;
+ } else
+ child->d_fsdata = NULL;
rc = ldiskfs_add_entry(oth->ot_handle, child, cinode);
RETURN(rc);
*/
static int osd_add_dot_dotdot(struct osd_thread_info *info,
struct osd_object *dir,
- struct osd_object *obj, const char *name,
+ struct inode *parent_dir, const char *name,
+ const struct dt_rec *dot_fid,
+ const struct dt_rec *dot_dot_fid,
struct thandle *th)
{
- struct inode *parent_dir = obj->oo_inode;
struct inode *inode = dir->oo_inode;
+ struct ldiskfs_dentry_param *dot_ldp;
+ struct ldiskfs_dentry_param *dot_dot_ldp;
struct osd_thandle *oth;
int result = 0;
if (dir->oo_compat_dot_created) {
result = -EEXIST;
} else {
- LASSERT(obj == dir);
+ LASSERT(inode == parent_dir);
dir->oo_compat_dot_created = 1;
result = 0;
}
} else if(strcmp(name, dotdot) == 0) {
+ dot_ldp = (struct ldiskfs_dentry_param *)info->oti_ldp;
+ dot_dot_ldp = (struct ldiskfs_dentry_param *)info->oti_ldp2;
+
if (!dir->oo_compat_dot_created)
return -EINVAL;
- if (dir->oo_compat_dotdot_created)
- return __osd_ea_add_rec(info, dir, obj, name, th);
+ if (fid_seq((struct lu_fid *) dot_fid) >= FID_SEQ_DISTRIBUTED_START) {
+ osd_get_ldiskfs_dirent_param(dot_ldp, dot_fid);
+ osd_get_ldiskfs_dirent_param(dot_dot_ldp, dot_dot_fid);
+ } else {
+ dot_ldp = NULL;
+ dot_dot_ldp = NULL;
+ }
+ /* in case of rename, dotdot is already created */
+ if (dir->oo_compat_dotdot_created) {
+ return __osd_ea_add_rec(info, dir, parent_dir, name,
+ dot_dot_fid, th);
+ }
- result = ldiskfs_add_dot_dotdot(oth->ot_handle, parent_dir, inode, NULL, NULL);
+ result = ldiskfs_add_dot_dotdot(oth->ot_handle, parent_dir, inode,
+ dot_ldp, dot_dot_ldp);
if (result == 0)
dir->oo_compat_dotdot_created = 1;
}
*/
static int osd_ea_add_rec(const struct lu_env *env,
struct osd_object *pobj,
- struct osd_object *cobj,
+ struct inode *cinode,
const char *name,
+ const struct dt_rec *fid,
struct thandle *th)
{
struct osd_thread_info *info = osd_oti_get(env);
if (name[0] == '.' && (name[1] == '\0' || (name[1] == '.' &&
name[2] =='\0')))
- rc = osd_add_dot_dotdot(info, pobj, cobj, name, th);
+ rc = osd_add_dot_dotdot(info, pobj, cinode, name,
+ (struct dt_rec *)lu_object_fid(&pobj->oo_dt.do_lu),
+ fid, th);
else
- rc = __osd_ea_add_rec(info, pobj, cobj, name, th);
+ rc = __osd_ea_add_rec(info, pobj, cinode, name, fid, th);
return rc;
}
dentry = osd_child_dentry_get(env, obj,
(char *)key, strlen((char *)key));
- down_read(&obj->oo_ext_idx_sem);
- bh = ldiskfs_find_entry(dentry, &de);
+ cfs_down_read(&obj->oo_ext_idx_sem);
+ bh = ll_ldiskfs_find_entry(dir, dentry, &de);
if (bh) {
ino = le32_to_cpu(de->inode);
+ rc = osd_get_fid_from_dentry(de, rec);
+
+ /* done with de, release bh */
brelse(bh);
- rc = osd_ea_fid_get(env, obj, ino, fid);
+ if (rc != 0)
+ rc = osd_ea_fid_get(env, obj, ino, fid);
} else
rc = -ENOENT;
- up_read(&obj->oo_ext_idx_sem);
+ cfs_up_read(&obj->oo_ext_idx_sem);
RETURN (rc);
}
else
current->cap_effective &= ~CFS_CAP_SYS_RESOURCE_MASK;
#endif
- down_write(&obj->oo_ext_idx_sem);
- rc = osd_ea_add_rec(env, obj, child, name, th);
- up_write(&obj->oo_ext_idx_sem);
+ cfs_down_write(&obj->oo_ext_idx_sem);
+ rc = osd_ea_add_rec(env, obj, child->oo_inode, name, rec, th);
+ cfs_up_write(&obj->oo_ext_idx_sem);
#ifdef HAVE_QUOTA_SUPPORT
current->cap_effective = save;
#endif
osd_object_put(env, child);
/* xtime should not be updated with server-side time. */
- spin_lock(&obj->oo_guard);
+ cfs_spin_lock(&obj->oo_guard);
inode->i_ctime = *ctime;
inode->i_mtime = *mtime;
- spin_unlock(&obj->oo_guard);
+ cfs_spin_unlock(&obj->oo_guard);
mark_inode_dirty(inode);
} else {
rc = PTR_ERR(child);
loff_t offset, __u64 ino,
unsigned d_type)
{
- struct osd_it_ea *it = (struct osd_it_ea *)buf;
- struct osd_it_ea_dirent *ent = it->oie_dirent;
+ struct osd_it_ea *it = (struct osd_it_ea *)buf;
+ struct osd_it_ea_dirent *ent = it->oie_dirent;
+ struct lu_fid *fid = &ent->oied_fid;
+ struct osd_fid_pack *rec;
ENTRY;
/* this should never happen */
OSD_IT_EA_BUFSIZE)
RETURN(1);
+ if (d_type & LDISKFS_DIRENT_LUFID) {
+ rec = (struct osd_fid_pack*) (name + namelen + 1);
+
+ if (osd_fid_unpack(fid, rec) != 0)
+ fid_zero(fid);
+
+ d_type &= ~LDISKFS_DIRENT_LUFID;
+ } else {
+ fid_zero(fid);
+ }
+
ent->oied_ino = ino;
ent->oied_off = offset;
ent->oied_namelen = namelen;
memcpy(ent->oied_name, name, namelen);
it->oie_rd_dirent++;
- it->oie_dirent = (void *) ent + size_round(sizeof(*ent) + namelen);
+ it->oie_dirent = (void *) ent + cfs_size_round(sizeof(*ent) + namelen);
RETURN(0);
}
it->oie_dirent = it->oie_buf;
it->oie_rd_dirent = 0;
- down_read(&obj->oo_ext_idx_sem);
+ cfs_down_read(&obj->oo_ext_idx_sem);
result = inode->i_fop->readdir(&it->oie_file, it,
(filldir_t) osd_ldiskfs_filldir);
- up_read(&obj->oo_ext_idx_sem);
+ cfs_up_read(&obj->oo_ext_idx_sem);
if (it->oie_rd_dirent == 0) {
result = -EIO;
ENTRY;
if (it->oie_it_dirent < it->oie_rd_dirent) {
- it->oie_dirent = (void *) it->oie_dirent +
- size_round(sizeof(struct osd_it_ea_dirent) +
- it->oie_dirent->oied_namelen);
+ it->oie_dirent =
+ (void *) it->oie_dirent +
+ cfs_size_round(sizeof(struct osd_it_ea_dirent) +
+ it->oie_dirent->oied_namelen);
it->oie_it_dirent++;
RETURN(0);
} else {
{
struct osd_it_ea *it = (struct osd_it_ea *)di;
struct osd_object *obj = it->oie_obj;
- struct osd_thread_info *info = osd_oti_get(env);
- struct lu_fid *fid = &info->oti_fid;
- int rc;
+ struct lu_fid *fid = &it->oie_dirent->oied_fid;
+ int rc = 0;
ENTRY;
- rc = osd_ea_fid_get(env, obj, it->oie_dirent->oied_ino, fid);
+ if (!fid_is_sane(fid))
+ rc = osd_ea_fid_get(env, obj, it->oie_dirent->oied_ino, fid);
if (rc == 0)
osd_it_pack_dirent(lde, fid, it->oie_dirent->oied_off,
l = osd2lu_dev(o);
l->ld_ops = &osd_lu_ops;
o->od_dt_dev.dd_ops = &osd_dt_ops;
- spin_lock_init(&o->od_osfs_lock);
+ cfs_spin_lock_init(&o->od_osfs_lock);
o->od_osfs_age = cfs_time_shift_64(-1000);
o->od_capa_hash = init_capa_hash();
if (o->od_capa_hash == NULL) {