cifs: add new cifs_iget function and convert unix codepath to use it
cifs: add new cifs_iget function and convert unix codepath to use it In order to unify some codepaths, introduce a common cifs_fattr struct for storing inode attributes. The different codepaths (unix, legacy, normal, etc...) can fill out this struct with inode info. It can then be passed as an arg to a common set of routines to get and update inodes. Add a new cifs_iget function that uses iget5_locked to identify inodes. This will compare inodes based on the uniqueid value in a cifs_fattr struct. Rather than filling out an already-created inode, have cifs_get_inode_info_unix instead fill out cifs_fattr and hand that off to cifs_iget. cifs_iget can then properly look for hardlinked inodes. On the readdir side, add a new cifs_readdir_lookup function that spawns populated dentries. Redefine FILE_UNIX_INFO so that it's basically a FILE_UNIX_BASIC_INFO that has a few fields wrapped around it. This allows us to more easily use the same function for filling out the fattr as the non-readdir codepath. With this, we should then have proper hardlink detection and can eventually get rid of some nasty CIFS-specific hacks for handing them. Signed-off-by: Jeff Layton <jlayton@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Steve French <sfrench@us.ibm.com>
This commit is contained in:

committed by
Steve French

parent
d960eea974
commit
cc0bad7552
@@ -188,6 +188,7 @@ int cifs_posix_open(char *full_path, struct inode **pinode,
|
||||
FILE_UNIX_BASIC_INFO *presp_data;
|
||||
__u32 posix_flags = 0;
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
|
||||
struct cifs_fattr fattr;
|
||||
|
||||
cFYI(1, ("posix open %s", full_path));
|
||||
|
||||
@@ -236,22 +237,21 @@ int cifs_posix_open(char *full_path, struct inode **pinode,
|
||||
if (presp_data->Type == cpu_to_le32(-1))
|
||||
goto posix_open_ret; /* open ok, caller does qpathinfo */
|
||||
|
||||
/* get new inode and set it up */
|
||||
if (!pinode)
|
||||
goto posix_open_ret; /* caller does not need info */
|
||||
|
||||
cifs_unix_basic_to_fattr(&fattr, presp_data, cifs_sb);
|
||||
|
||||
/* get new inode and set it up */
|
||||
if (*pinode == NULL) {
|
||||
__u64 unique_id = le64_to_cpu(presp_data->UniqueId);
|
||||
*pinode = cifs_new_inode(sb, &unique_id);
|
||||
*pinode = cifs_iget(sb, &fattr);
|
||||
if (!*pinode) {
|
||||
rc = -ENOMEM;
|
||||
goto posix_open_ret;
|
||||
}
|
||||
} else {
|
||||
cifs_fattr_to_inode(*pinode, &fattr);
|
||||
}
|
||||
/* else an inode was passed in. Update its info, don't create one */
|
||||
|
||||
/* We do not need to close the file if new_inode fails since
|
||||
the caller will retry qpathinfo as long as inode is null */
|
||||
if (*pinode == NULL)
|
||||
goto posix_open_ret;
|
||||
|
||||
posix_fill_in_inode(*pinode, presp_data, 1);
|
||||
|
||||
cifs_fill_fileinfo(*pinode, *pnetfid, cifs_sb->tcon, write_only);
|
||||
|
||||
|
Reference in New Issue
Block a user