Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 125793
b: refs/heads/master
c: f5d3620
h: refs/heads/master
i:
  125791: 849cec6
v: v3
  • Loading branch information
Tiger Yang authored and Mark Fasheh committed Jan 5, 2009
1 parent 185c326 commit 58d50c1
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 45 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: fecc01126d7a244b7e9b563c80663ffdca35343b
refs/heads/master: f5d362022a947e84b0a3dd656d09c6b2322e234f
108 changes: 64 additions & 44 deletions trunk/fs/ocfs2/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,12 @@

static int ocfs2_mknod_locked(struct ocfs2_super *osb,
struct inode *dir,
struct dentry *dentry, int mode,
struct inode *inode,
struct dentry *dentry,
dev_t dev,
struct buffer_head **new_fe_bh,
struct buffer_head *parent_fe_bh,
handle_t *handle,
struct inode **ret_inode,
struct ocfs2_alloc_context *inode_ac);

static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb,
Expand Down Expand Up @@ -186,6 +186,34 @@ static struct dentry *ocfs2_lookup(struct inode *dir, struct dentry *dentry,
return ret;
}

static struct inode *ocfs2_get_init_inode(struct inode *dir, int mode)
{
struct inode *inode;

inode = new_inode(dir->i_sb);
if (!inode) {
mlog(ML_ERROR, "new_inode failed!\n");
return NULL;
}

/* populate as many fields early on as possible - many of
* these are used by the support functions here and in
* callers. */
if (S_ISDIR(mode))
inode->i_nlink = 2;
else
inode->i_nlink = 1;
inode->i_uid = current_fsuid();
if (dir->i_mode & S_ISGID) {
inode->i_gid = dir->i_gid;
if (S_ISDIR(mode))
mode |= S_ISGID;
} else
inode->i_gid = current_fsgid();
inode->i_mode = mode;
return inode;
}

static int ocfs2_mknod(struct inode *dir,
struct dentry *dentry,
int mode,
Expand Down Expand Up @@ -250,6 +278,13 @@ static int ocfs2_mknod(struct inode *dir,
goto leave;
}

inode = ocfs2_get_init_inode(dir, mode);
if (!inode) {
status = -ENOMEM;
mlog_errno(status);
goto leave;
}

/* Reserve a cluster if creating an extent based directory. */
if (S_ISDIR(mode) && !ocfs2_supports_inline_data(osb)) {
status = ocfs2_reserve_clusters(osb, 1, &data_ac);
Expand All @@ -269,9 +304,9 @@ static int ocfs2_mknod(struct inode *dir,
}

/* do the real work now. */
status = ocfs2_mknod_locked(osb, dir, dentry, mode, dev,
status = ocfs2_mknod_locked(osb, dir, inode, dentry, dev,
&new_fe_bh, parent_fe_bh, handle,
&inode, inode_ac);
inode_ac);
if (status < 0) {
mlog_errno(status);
goto leave;
Expand Down Expand Up @@ -332,8 +367,10 @@ static int ocfs2_mknod(struct inode *dir,
brelse(de_bh);
brelse(parent_fe_bh);

if ((status < 0) && inode)
if ((status < 0) && inode) {
clear_nlink(inode);
iput(inode);
}

if (inode_ac)
ocfs2_free_alloc_context(inode_ac);
Expand All @@ -348,27 +385,25 @@ static int ocfs2_mknod(struct inode *dir,

static int ocfs2_mknod_locked(struct ocfs2_super *osb,
struct inode *dir,
struct dentry *dentry, int mode,
struct inode *inode,
struct dentry *dentry,
dev_t dev,
struct buffer_head **new_fe_bh,
struct buffer_head *parent_fe_bh,
handle_t *handle,
struct inode **ret_inode,
struct ocfs2_alloc_context *inode_ac)
{
int status = 0;
struct ocfs2_dinode *fe = NULL;
struct ocfs2_extent_list *fel;
u64 fe_blkno = 0;
u16 suballoc_bit;
struct inode *inode = NULL;

mlog_entry("(0x%p, 0x%p, %d, %lu, '%.*s')\n", dir, dentry, mode,
(unsigned long)dev, dentry->d_name.len,
mlog_entry("(0x%p, 0x%p, %d, %lu, '%.*s')\n", dir, dentry,
inode->i_mode, (unsigned long)dev, dentry->d_name.len,
dentry->d_name.name);

*new_fe_bh = NULL;
*ret_inode = NULL;

status = ocfs2_claim_new_inode(osb, handle, inode_ac, &suballoc_bit,
&fe_blkno);
Expand All @@ -377,23 +412,11 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb,
goto leave;
}

inode = new_inode(dir->i_sb);
if (!inode) {
status = -ENOMEM;
mlog(ML_ERROR, "new_inode failed!\n");
goto leave;
}

/* populate as many fields early on as possible - many of
* these are used by the support functions here and in
* callers. */
inode->i_ino = ino_from_blkno(osb->sb, fe_blkno);
OCFS2_I(inode)->ip_blkno = fe_blkno;
if (S_ISDIR(mode))
inode->i_nlink = 2;
else
inode->i_nlink = 1;
inode->i_mode = mode;
spin_lock(&osb->osb_lock);
inode->i_generation = osb->s_next_generation++;
spin_unlock(&osb->osb_lock);
Expand Down Expand Up @@ -421,17 +444,11 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb,
fe->i_blkno = cpu_to_le64(fe_blkno);
fe->i_suballoc_bit = cpu_to_le16(suballoc_bit);
fe->i_suballoc_slot = cpu_to_le16(inode_ac->ac_alloc_slot);
fe->i_uid = cpu_to_le32(current_fsuid());
if (dir->i_mode & S_ISGID) {
fe->i_gid = cpu_to_le32(dir->i_gid);
if (S_ISDIR(mode))
mode |= S_ISGID;
} else
fe->i_gid = cpu_to_le32(current_fsgid());
fe->i_mode = cpu_to_le16(mode);
if (S_ISCHR(mode) || S_ISBLK(mode))
fe->i_uid = cpu_to_le32(inode->i_uid);
fe->i_gid = cpu_to_le32(inode->i_gid);
fe->i_mode = cpu_to_le16(inode->i_mode);
if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
fe->id1.dev1.i_rdev = cpu_to_le64(huge_encode_dev(dev));

fe->i_links_count = cpu_to_le16(inode->i_nlink);

fe->i_last_eb_blk = 0;
Expand All @@ -446,7 +463,7 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb,
/*
* If supported, directories start with inline data.
*/
if (S_ISDIR(mode) && ocfs2_supports_inline_data(osb)) {
if (S_ISDIR(inode->i_mode) && ocfs2_supports_inline_data(osb)) {
u16 feat = le16_to_cpu(fe->i_dyn_features);

fe->i_dyn_features = cpu_to_le16(feat | OCFS2_INLINE_DATA_FL);
Expand Down Expand Up @@ -484,17 +501,12 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb,
status = 0; /* error in ocfs2_create_new_inode_locks is not
* critical */

*ret_inode = inode;
leave:
if (status < 0) {
if (*new_fe_bh) {
brelse(*new_fe_bh);
*new_fe_bh = NULL;
}
if (inode) {
clear_nlink(inode);
iput(inode);
}
}

mlog_exit(status);
Expand Down Expand Up @@ -1542,6 +1554,13 @@ static int ocfs2_symlink(struct inode *dir,
goto bail;
}

inode = ocfs2_get_init_inode(dir, S_IFLNK | S_IRWXUGO);
if (!inode) {
status = -ENOMEM;
mlog_errno(status);
goto bail;
}

/* don't reserve bitmap space for fast symlinks. */
if (l > ocfs2_fast_symlink_chars(sb)) {
status = ocfs2_reserve_clusters(osb, 1, &data_ac);
Expand All @@ -1560,10 +1579,9 @@ static int ocfs2_symlink(struct inode *dir,
goto bail;
}

status = ocfs2_mknod_locked(osb, dir, dentry,
S_IFLNK | S_IRWXUGO, 0,
&new_fe_bh, parent_fe_bh, handle,
&inode, inode_ac);
status = ocfs2_mknod_locked(osb, dir, inode, dentry,
0, &new_fe_bh, parent_fe_bh, handle,
inode_ac);
if (status < 0) {
mlog_errno(status);
goto bail;
Expand Down Expand Up @@ -1644,8 +1662,10 @@ static int ocfs2_symlink(struct inode *dir,
ocfs2_free_alloc_context(inode_ac);
if (data_ac)
ocfs2_free_alloc_context(data_ac);
if ((status < 0) && inode)
if ((status < 0) && inode) {
clear_nlink(inode);
iput(inode);
}

mlog_exit(status);

Expand Down

0 comments on commit 58d50c1

Please sign in to comment.