Skip to content

Commit

Permalink
cifs: refactor new_inode() calls and inode initialization
Browse files Browse the repository at this point in the history
Move new inode creation into a separate routine and refactor the
callers to take advantage of it.

Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
  • Loading branch information
jtlayton authored and Steve French committed Feb 21, 2009
1 parent e4cce94 commit 132ac7b
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 66 deletions.
2 changes: 2 additions & 0 deletions fs/cifs/cifsproto.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ extern u64 cifs_UnixTimeToNT(struct timespec);
extern __le64 cnvrtDosCifsTm(__u16 date, __u16 time);
extern struct timespec cnvrtDosUnixTm(__u16 date, __u16 time);

extern struct inode *cifs_new_inode(struct super_block *sb,
unsigned long *inum);
extern int cifs_get_inode_info(struct inode **pinode,
const unsigned char *search_path,
FILE_ALL_INFO *pfile_info,
Expand Down
96 changes: 60 additions & 36 deletions fs/cifs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,49 @@ static void fill_fake_finddataunix(FILE_UNIX_BASIC_INFO *pfnd_dat,
pfnd_dat->Gid = cpu_to_le64(pinode->i_gid);
}

/**
* cifs_new inode - create new inode, initialize, and hash it
* @sb - pointer to superblock
* @inum - if valid pointer and serverino is enabled, replace i_ino with val
*
* Create a new inode, initialize it for CIFS and hash it. Returns the new
* inode or NULL if one couldn't be allocated.
*
* If the share isn't mounted with "serverino" or inum is a NULL pointer then
* we'll just use the inode number assigned by new_inode(). Note that this can
* mean i_ino collisions since the i_ino assigned by new_inode is not
* guaranteed to be unique.
*/
struct inode *
cifs_new_inode(struct super_block *sb, unsigned long *inum)
{
struct inode *inode;

inode = new_inode(sb);
if (inode == NULL)
return NULL;

/*
* BB: Is i_ino == 0 legal? Here, we assume that it is. If it isn't we
* stop passing inum as ptr. Are there sanity checks we can use to
* ensure that the server is really filling in that field? Also,
* if serverino is disabled, perhaps we should be using iunique()?
*/
if (inum && (CIFS_SB(sb)->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM))
inode->i_ino = *inum;

/*
* must set this here instead of cifs_alloc_inode since VFS will
* clobber i_flags
*/
if (sb->s_flags & MS_NOATIME)
inode->i_flags |= S_NOATIME | S_NOCMTIME;

insert_inode_hash(inode);

return inode;
}

int cifs_get_inode_info_unix(struct inode **pinode,
const unsigned char *full_path, struct super_block *sb, int xid)
{
Expand Down Expand Up @@ -233,22 +276,12 @@ int cifs_get_inode_info_unix(struct inode **pinode,

/* get new inode */
if (*pinode == NULL) {
*pinode = new_inode(sb);
*pinode = cifs_new_inode(sb, (unsigned long *)
&find_data.UniqueId);
if (*pinode == NULL) {
rc = -ENOMEM;
goto cgiiu_exit;
}
/* Is an i_ino of zero legal? */
/* note ino incremented to unique num in new_inode */
/* Are there sanity checks we can use to ensure that
the server is really filling in that field? */
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)
(*pinode)->i_ino = (unsigned long)find_data.UniqueId;

if (sb->s_flags & MS_NOATIME)
(*pinode)->i_flags |= S_NOATIME | S_NOCMTIME;

insert_inode_hash(*pinode);
}

inode = *pinode;
Expand Down Expand Up @@ -465,11 +498,8 @@ int cifs_get_inode_info(struct inode **pinode,

/* get new inode */
if (*pinode == NULL) {
*pinode = new_inode(sb);
if (*pinode == NULL) {
rc = -ENOMEM;
goto cgii_exit;
}
__u64 inode_num;

/* Is an i_ino of zero legal? Can we use that to check
if the server supports returning inode numbers? Are
there other sanity checks we can use to ensure that
Expand All @@ -486,7 +516,6 @@ int cifs_get_inode_info(struct inode **pinode,

if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
int rc1 = 0;
__u64 inode_num;

rc1 = CIFSGetSrvInodeNumber(xid, pTcon,
full_path, &inode_num,
Expand All @@ -496,12 +525,17 @@ int cifs_get_inode_info(struct inode **pinode,
if (rc1) {
cFYI(1, ("GetSrvInodeNum rc %d", rc1));
/* BB EOPNOSUPP disable SERVER_INUM? */
} else /* do we need cast or hash to ino? */
(*pinode)->i_ino = inode_num;
} /* else ino incremented to unique num in new_inode*/
if (sb->s_flags & MS_NOATIME)
(*pinode)->i_flags |= S_NOATIME | S_NOCMTIME;
insert_inode_hash(*pinode);
}
*pinode = cifs_new_inode(sb, (unsigned long *)
&inode_num);
} else {
*pinode = cifs_new_inode(sb, NULL);
}

if (*pinode == NULL) {
rc = -ENOMEM;
goto cgii_exit;
}
}
inode = *pinode;
cifsInfo = CIFS_I(inode);
Expand Down Expand Up @@ -1114,24 +1148,14 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
else
direntry->d_op = &cifs_dentry_ops;

newinode = new_inode(inode->i_sb);
newinode = cifs_new_inode(inode->i_sb, (unsigned long *)
&pInfo->UniqueId);
if (newinode == NULL) {
kfree(pInfo);
goto mkdir_get_info;
}

/* Is an i_ino of zero legal? */
/* Are there sanity checks we can use to ensure that
the server is really filling in that field? */
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
newinode->i_ino =
(unsigned long)pInfo->UniqueId;
} /* note ino incremented to unique num in new_inode */
if (inode->i_sb->s_flags & MS_NOATIME)
newinode->i_flags |= S_NOATIME | S_NOCMTIME;
newinode->i_nlink = 2;

insert_inode_hash(newinode);
d_instantiate(direntry, newinode);

/* we already checked in POSIXCreate whether
Expand Down
54 changes: 24 additions & 30 deletions fs/cifs/readdir.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,35 +56,34 @@ static inline void dump_cifs_file_struct(struct file *file, char *label)
}
#endif /* DEBUG2 */

/* Returns one if new inode created (which therefore needs to be hashed) */
/* Returns 1 if new inode created, 2 if both dentry and inode were */
/* Might check in the future if inode number changed so we can rehash inode */
static int construct_dentry(struct qstr *qstring, struct file *file,
struct inode **ptmp_inode, struct dentry **pnew_dentry)
static int
construct_dentry(struct qstr *qstring, struct file *file,
struct inode **ptmp_inode, struct dentry **pnew_dentry,
unsigned long *inum)
{
struct dentry *tmp_dentry;
struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *pTcon;
struct dentry *tmp_dentry = NULL;
struct super_block *sb = file->f_path.dentry->d_sb;
int rc = 0;

cFYI(1, ("For %s", qstring->name));
cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
pTcon = cifs_sb->tcon;

qstring->hash = full_name_hash(qstring->name, qstring->len);
tmp_dentry = d_lookup(file->f_path.dentry, qstring);
if (tmp_dentry) {
/* BB: overwrite old name? i.e. tmp_dentry->d_name and
* tmp_dentry->d_name.len??
*/
cFYI(0, ("existing dentry with inode 0x%p",
tmp_dentry->d_inode));
*ptmp_inode = tmp_dentry->d_inode;
/* BB overwrite old name? i.e. tmp_dentry->d_name and tmp_dentry->d_name.len??*/
if (*ptmp_inode == NULL) {
*ptmp_inode = new_inode(file->f_path.dentry->d_sb);
*ptmp_inode = cifs_new_inode(sb, inum);
if (*ptmp_inode == NULL)
return rc;
rc = 1;
}
if (file->f_path.dentry->d_sb->s_flags & MS_NOATIME)
(*ptmp_inode)->i_flags |= S_NOATIME | S_NOCMTIME;
} else {
tmp_dentry = d_alloc(file->f_path.dentry, qstring);
if (tmp_dentry == NULL) {
Expand All @@ -93,15 +92,14 @@ static int construct_dentry(struct qstr *qstring, struct file *file,
return rc;
}

*ptmp_inode = new_inode(file->f_path.dentry->d_sb);
if (pTcon->nocase)
if (CIFS_SB(sb)->tcon->nocase)
tmp_dentry->d_op = &cifs_ci_dentry_ops;
else
tmp_dentry->d_op = &cifs_dentry_ops;

*ptmp_inode = cifs_new_inode(sb, inum);
if (*ptmp_inode == NULL)
return rc;
if (file->f_path.dentry->d_sb->s_flags & MS_NOATIME)
(*ptmp_inode)->i_flags |= S_NOATIME | S_NOCMTIME;
rc = 2;
}

Expand Down Expand Up @@ -842,9 +840,7 @@ static int cifs_get_name_from_search_buf(struct qstr *pqst,
len = strnlen(filename, PATH_MAX);
}

/* BB fixme - hash low and high 32 bits if not 64 bit arch BB */
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)
*pinum = pFindData->UniqueId;
*pinum = pFindData->UniqueId;
} else if (level == SMB_FIND_FILE_DIRECTORY_INFO) {
FILE_DIRECTORY_INFO *pFindData =
(FILE_DIRECTORY_INFO *)current_entry;
Expand Down Expand Up @@ -940,20 +936,18 @@ static int cifs_filldir(char *pfindEntry, struct file *file,
if (rc)
return rc;

rc = construct_dentry(&qstring, file, &tmp_inode, &tmp_dentry);
/* only these two infolevels return valid inode numbers */
if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_UNIX ||
pCifsF->srch_inf.info_level == SMB_FIND_FILE_ID_FULL_DIR_INFO)
rc = construct_dentry(&qstring, file, &tmp_inode, &tmp_dentry,
&inum);
else
rc = construct_dentry(&qstring, file, &tmp_inode, &tmp_dentry,
NULL);

if ((tmp_inode == NULL) || (tmp_dentry == NULL))
return -ENOMEM;

if (rc) {
/* inode created, we need to hash it with right inode number */
if (inum != 0) {
/* BB fixme - hash the 2 32 quantities bits together if
* necessary BB */
tmp_inode->i_ino = inum;
}
insert_inode_hash(tmp_inode);
}

/* we pass in rc below, indicating whether it is a new inode,
so we can figure out whether to invalidate the inode cached
data if the file has changed */
Expand Down

0 comments on commit 132ac7b

Please sign in to comment.