diff options
author | Jeff Layton <jlayton@redhat.com> | 2009-06-25 00:56:52 -0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2009-07-01 17:26:42 -0400 |
commit | cc0bad7552308e8905d6ea56e6b7811fa67e716d (patch) | |
tree | c02a91f13a502f444330b91b36ab12f55f352268 /fs/cifs/dir.c | |
parent | d960eea974f5e500c0dcb95a934239cc1f481cfd (diff) |
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>
Diffstat (limited to 'fs/cifs/dir.c')
-rw-r--r-- | fs/cifs/dir.c | 22 |
1 files changed, 11 insertions, 11 deletions
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 7dc6b74f9def..a40054faed7f 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
@@ -188,6 +188,7 @@ int cifs_posix_open(char *full_path, struct inode **pinode, | |||
188 | FILE_UNIX_BASIC_INFO *presp_data; | 188 | FILE_UNIX_BASIC_INFO *presp_data; |
189 | __u32 posix_flags = 0; | 189 | __u32 posix_flags = 0; |
190 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); | 190 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
191 | struct cifs_fattr fattr; | ||
191 | 192 | ||
192 | cFYI(1, ("posix open %s", full_path)); | 193 | cFYI(1, ("posix open %s", full_path)); |
193 | 194 | ||
@@ -236,22 +237,21 @@ int cifs_posix_open(char *full_path, struct inode **pinode, | |||
236 | if (presp_data->Type == cpu_to_le32(-1)) | 237 | if (presp_data->Type == cpu_to_le32(-1)) |
237 | goto posix_open_ret; /* open ok, caller does qpathinfo */ | 238 | goto posix_open_ret; /* open ok, caller does qpathinfo */ |
238 | 239 | ||
239 | /* get new inode and set it up */ | ||
240 | if (!pinode) | 240 | if (!pinode) |
241 | goto posix_open_ret; /* caller does not need info */ | 241 | goto posix_open_ret; /* caller does not need info */ |
242 | 242 | ||
243 | cifs_unix_basic_to_fattr(&fattr, presp_data, cifs_sb); | ||
244 | |||
245 | /* get new inode and set it up */ | ||
243 | if (*pinode == NULL) { | 246 | if (*pinode == NULL) { |
244 | __u64 unique_id = le64_to_cpu(presp_data->UniqueId); | 247 | *pinode = cifs_iget(sb, &fattr); |
245 | *pinode = cifs_new_inode(sb, &unique_id); | 248 | if (!*pinode) { |
249 | rc = -ENOMEM; | ||
250 | goto posix_open_ret; | ||
251 | } | ||
252 | } else { | ||
253 | cifs_fattr_to_inode(*pinode, &fattr); | ||
246 | } | 254 | } |
247 | /* else an inode was passed in. Update its info, don't create one */ | ||
248 | |||
249 | /* We do not need to close the file if new_inode fails since | ||
250 | the caller will retry qpathinfo as long as inode is null */ | ||
251 | if (*pinode == NULL) | ||
252 | goto posix_open_ret; | ||
253 | |||
254 | posix_fill_in_inode(*pinode, presp_data, 1); | ||
255 | 255 | ||
256 | cifs_fill_fileinfo(*pinode, *pnetfid, cifs_sb->tcon, write_only); | 256 | cifs_fill_fileinfo(*pinode, *pnetfid, cifs_sb->tcon, write_only); |
257 | 257 | ||