aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2009-06-25 00:56:52 -0400
committerSteve French <sfrench@us.ibm.com>2009-07-01 17:26:42 -0400
commitcc0bad7552308e8905d6ea56e6b7811fa67e716d (patch)
treec02a91f13a502f444330b91b36ab12f55f352268 /fs/cifs
parentd960eea974f5e500c0dcb95a934239cc1f481cfd (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')
-rw-r--r--fs/cifs/cifsfs.h13
-rw-r--r--fs/cifs/cifsglob.h25
-rw-r--r--fs/cifs/cifspdu.h14
-rw-r--r--fs/cifs/cifsproto.h9
-rw-r--r--fs/cifs/dir.c22
-rw-r--r--fs/cifs/inode.c380
-rw-r--r--fs/cifs/readdir.c253
7 files changed, 339 insertions, 377 deletions
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index 9570a0e8023f..586df24c9abb 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -24,6 +24,19 @@
24 24
25#define ROOT_I 2 25#define ROOT_I 2
26 26
27/*
28 * ino_t is 32-bits on 32-bit arch. We have to squash the 64-bit value down
29 * so that it will fit.
30 */
31static inline ino_t
32cifs_uniqueid_to_ino_t(u64 fileid)
33{
34 ino_t ino = (ino_t) fileid;
35 if (sizeof(ino_t) < sizeof(u64))
36 ino ^= fileid >> (sizeof(u64)-sizeof(ino_t)) * 8;
37 return ino;
38}
39
27extern struct file_system_type cifs_fs_type; 40extern struct file_system_type cifs_fs_type;
28extern const struct address_space_operations cifs_addr_ops; 41extern const struct address_space_operations cifs_addr_ops;
29extern const struct address_space_operations cifs_addr_ops_smallbuf; 42extern const struct address_space_operations cifs_addr_ops_smallbuf;
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index e1225e6ded2f..e6435cba8113 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -371,6 +371,7 @@ struct cifsInodeInfo {
371 bool oplockPending:1; 371 bool oplockPending:1;
372 bool delete_pending:1; /* DELETE_ON_CLOSE is set */ 372 bool delete_pending:1; /* DELETE_ON_CLOSE is set */
373 u64 server_eof; /* current file size on server */ 373 u64 server_eof; /* current file size on server */
374 u64 uniqueid; /* server inode number */
374 struct inode vfs_inode; 375 struct inode vfs_inode;
375}; 376};
376 377
@@ -472,6 +473,30 @@ struct dfs_info3_param {
472 char *node_name; 473 char *node_name;
473}; 474};
474 475
476/*
477 * common struct for holding inode info when searching for or updating an
478 * inode with new info
479 */
480
481#define CIFS_FATTR_DFS_REFERRAL 0x1
482
483struct cifs_fattr {
484 u32 cf_flags;
485 u32 cf_cifsattrs;
486 u64 cf_uniqueid;
487 u64 cf_eof;
488 u64 cf_bytes;
489 uid_t cf_uid;
490 gid_t cf_gid;
491 umode_t cf_mode;
492 dev_t cf_rdev;
493 unsigned int cf_nlink;
494 unsigned int cf_dtype;
495 struct timespec cf_atime;
496 struct timespec cf_mtime;
497 struct timespec cf_ctime;
498};
499
475static inline void free_dfs_info_param(struct dfs_info3_param *param) 500static inline void free_dfs_info_param(struct dfs_info3_param *param)
476{ 501{
477 if (param) { 502 if (param) {
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h
index a785f69dbc9f..2d07f890a842 100644
--- a/fs/cifs/cifspdu.h
+++ b/fs/cifs/cifspdu.h
@@ -2328,19 +2328,7 @@ struct file_attrib_tag {
2328typedef struct { 2328typedef struct {
2329 __le32 NextEntryOffset; 2329 __le32 NextEntryOffset;
2330 __u32 ResumeKey; /* as with FileIndex - no need to convert */ 2330 __u32 ResumeKey; /* as with FileIndex - no need to convert */
2331 __le64 EndOfFile; 2331 FILE_UNIX_BASIC_INFO basic;
2332 __le64 NumOfBytes;
2333 __le64 LastStatusChange; /*SNIA specs DCE time for the 3 time fields */
2334 __le64 LastAccessTime;
2335 __le64 LastModificationTime;
2336 __le64 Uid;
2337 __le64 Gid;
2338 __le32 Type;
2339 __le64 DevMajor;
2340 __le64 DevMinor;
2341 __le64 UniqueId;
2342 __le64 Permissions;
2343 __le64 Nlinks;
2344 char FileName[1]; 2332 char FileName[1];
2345} __attribute__((packed)) FILE_UNIX_INFO; /* level 0x202 */ 2333} __attribute__((packed)) FILE_UNIX_INFO; /* level 0x202 */
2346 2334
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index c419416a42ee..b2bd83fd2aa4 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -98,9 +98,14 @@ extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time,
98extern int cifs_posix_open(char *full_path, struct inode **pinode, 98extern int cifs_posix_open(char *full_path, struct inode **pinode,
99 struct super_block *sb, int mode, int oflags, 99 struct super_block *sb, int mode, int oflags,
100 int *poplock, __u16 *pnetfid, int xid); 100 int *poplock, __u16 *pnetfid, int xid);
101extern void posix_fill_in_inode(struct inode *tmp_inode, 101extern void cifs_unix_basic_to_fattr(struct cifs_fattr *fattr,
102 FILE_UNIX_BASIC_INFO *pData, int isNewInode); 102 FILE_UNIX_BASIC_INFO *info,
103 struct cifs_sb_info *cifs_sb);
104extern void cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr);
103extern struct inode *cifs_new_inode(struct super_block *sb, __u64 *inum); 105extern struct inode *cifs_new_inode(struct super_block *sb, __u64 *inum);
106extern struct inode *cifs_iget(struct super_block *sb,
107 struct cifs_fattr *fattr);
108
104extern int cifs_get_inode_info(struct inode **pinode, 109extern int cifs_get_inode_info(struct inode **pinode,
105 const unsigned char *search_path, 110 const unsigned char *search_path,
106 FILE_ALL_INFO *pfile_info, 111 FILE_ALL_INFO *pfile_info,
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
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 155c9e785d0c..b22379610d71 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -77,127 +77,146 @@ static void cifs_set_ops(struct inode *inode, const bool is_dfs_referral)
77 } 77 }
78} 78}
79 79
80static void cifs_unix_info_to_inode(struct inode *inode, 80/* populate an inode with info from a cifs_fattr struct */
81 FILE_UNIX_BASIC_INFO *info, int force_uid_gid) 81void
82cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
82{ 83{
83 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 84 struct cifsInodeInfo *cifs_i = CIFS_I(inode);
84 struct cifsInodeInfo *cifsInfo = CIFS_I(inode); 85 unsigned long now = jiffies;
85 __u64 num_of_bytes = le64_to_cpu(info->NumOfBytes); 86
86 __u64 end_of_file = le64_to_cpu(info->EndOfFile); 87 inode->i_atime = fattr->cf_atime;
88 inode->i_mtime = fattr->cf_mtime;
89 inode->i_ctime = fattr->cf_ctime;
90 inode->i_mode = fattr->cf_mode;
91 inode->i_rdev = fattr->cf_rdev;
92 inode->i_nlink = fattr->cf_nlink;
93 inode->i_uid = fattr->cf_uid;
94 inode->i_gid = fattr->cf_gid;
95
96 cifs_i->cifsAttrs = fattr->cf_cifsattrs;
97 cifs_i->uniqueid = fattr->cf_uniqueid;
98
99 cFYI(1, ("inode 0x%p old_time=%ld new_time=%ld", inode,
100 cifs_i->time, now));
101 cifs_i->time = now;
102
103 /*
104 * Can't safely change the file size here if the client is writing to
105 * it due to potential races.
106 */
107 spin_lock(&inode->i_lock);
108 if (is_size_safe_to_change(cifs_i, fattr->cf_eof)) {
109 i_size_write(inode, fattr->cf_eof);
110
111 /*
112 * i_blocks is not related to (i_size / i_blksize),
113 * but instead 512 byte (2**9) size is required for
114 * calculating num blocks.
115 */
116 inode->i_blocks = (512 - 1 + fattr->cf_bytes) >> 9;
117 }
118 spin_unlock(&inode->i_lock);
119
120 cifs_set_ops(inode, fattr->cf_flags & CIFS_FATTR_DFS_REFERRAL);
121}
122
123/* Fill a cifs_fattr struct with info from FILE_UNIX_BASIC_INFO. */
124void
125cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, FILE_UNIX_BASIC_INFO *info,
126 struct cifs_sb_info *cifs_sb)
127{
128 memset(fattr, 0, sizeof(*fattr));
129 fattr->cf_uniqueid = le64_to_cpu(info->UniqueId);
130 fattr->cf_bytes = le64_to_cpu(info->NumOfBytes);
131 fattr->cf_eof = le64_to_cpu(info->EndOfFile);
87 132
88 inode->i_atime = cifs_NTtimeToUnix(info->LastAccessTime); 133 fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime);
89 inode->i_mtime = 134 fattr->cf_mtime = cifs_NTtimeToUnix(info->LastModificationTime);
90 cifs_NTtimeToUnix(info->LastModificationTime); 135 fattr->cf_ctime = cifs_NTtimeToUnix(info->LastStatusChange);
91 inode->i_ctime = cifs_NTtimeToUnix(info->LastStatusChange); 136 fattr->cf_mode = le64_to_cpu(info->Permissions);
92 inode->i_mode = le64_to_cpu(info->Permissions);
93 137
94 /* 138 /*
95 * Since we set the inode type below we need to mask off 139 * Since we set the inode type below we need to mask off
96 * to avoid strange results if bits set above. 140 * to avoid strange results if bits set above.
97 */ 141 */
98 inode->i_mode &= ~S_IFMT; 142 fattr->cf_mode &= ~S_IFMT;
99 switch (le32_to_cpu(info->Type)) { 143 switch (le32_to_cpu(info->Type)) {
100 case UNIX_FILE: 144 case UNIX_FILE:
101 inode->i_mode |= S_IFREG; 145 fattr->cf_mode |= S_IFREG;
146 fattr->cf_dtype = DT_REG;
102 break; 147 break;
103 case UNIX_SYMLINK: 148 case UNIX_SYMLINK:
104 inode->i_mode |= S_IFLNK; 149 fattr->cf_mode |= S_IFLNK;
150 fattr->cf_dtype = DT_LNK;
105 break; 151 break;
106 case UNIX_DIR: 152 case UNIX_DIR:
107 inode->i_mode |= S_IFDIR; 153 fattr->cf_mode |= S_IFDIR;
154 fattr->cf_dtype = DT_DIR;
108 break; 155 break;
109 case UNIX_CHARDEV: 156 case UNIX_CHARDEV:
110 inode->i_mode |= S_IFCHR; 157 fattr->cf_mode |= S_IFCHR;
111 inode->i_rdev = MKDEV(le64_to_cpu(info->DevMajor), 158 fattr->cf_dtype = DT_CHR;
112 le64_to_cpu(info->DevMinor) & MINORMASK); 159 fattr->cf_rdev = MKDEV(le64_to_cpu(info->DevMajor),
160 le64_to_cpu(info->DevMinor) & MINORMASK);
113 break; 161 break;
114 case UNIX_BLOCKDEV: 162 case UNIX_BLOCKDEV:
115 inode->i_mode |= S_IFBLK; 163 fattr->cf_mode |= S_IFBLK;
116 inode->i_rdev = MKDEV(le64_to_cpu(info->DevMajor), 164 fattr->cf_dtype = DT_BLK;
117 le64_to_cpu(info->DevMinor) & MINORMASK); 165 fattr->cf_rdev = MKDEV(le64_to_cpu(info->DevMajor),
166 le64_to_cpu(info->DevMinor) & MINORMASK);
118 break; 167 break;
119 case UNIX_FIFO: 168 case UNIX_FIFO:
120 inode->i_mode |= S_IFIFO; 169 fattr->cf_mode |= S_IFIFO;
170 fattr->cf_dtype = DT_FIFO;
121 break; 171 break;
122 case UNIX_SOCKET: 172 case UNIX_SOCKET:
123 inode->i_mode |= S_IFSOCK; 173 fattr->cf_mode |= S_IFSOCK;
174 fattr->cf_dtype = DT_SOCK;
124 break; 175 break;
125 default: 176 default:
126 /* safest to call it a file if we do not know */ 177 /* safest to call it a file if we do not know */
127 inode->i_mode |= S_IFREG; 178 fattr->cf_mode |= S_IFREG;
179 fattr->cf_dtype = DT_REG;
128 cFYI(1, ("unknown type %d", le32_to_cpu(info->Type))); 180 cFYI(1, ("unknown type %d", le32_to_cpu(info->Type)));
129 break; 181 break;
130 } 182 }
131 183
132 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) && 184 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)
133 !force_uid_gid) 185 fattr->cf_uid = cifs_sb->mnt_uid;
134 inode->i_uid = cifs_sb->mnt_uid;
135 else 186 else
136 inode->i_uid = le64_to_cpu(info->Uid); 187 fattr->cf_uid = le64_to_cpu(info->Uid);
137 188
138 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) && 189 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)
139 !force_uid_gid) 190 fattr->cf_gid = cifs_sb->mnt_gid;
140 inode->i_gid = cifs_sb->mnt_gid;
141 else 191 else
142 inode->i_gid = le64_to_cpu(info->Gid); 192 fattr->cf_gid = le64_to_cpu(info->Gid);
143 193
144 inode->i_nlink = le64_to_cpu(info->Nlinks); 194 fattr->cf_nlink = le64_to_cpu(info->Nlinks);
145
146 cifsInfo->server_eof = end_of_file;
147 spin_lock(&inode->i_lock);
148 if (is_size_safe_to_change(cifsInfo, end_of_file)) {
149 /*
150 * We can not safely change the file size here if the client
151 * is writing to it due to potential races.
152 */
153 i_size_write(inode, end_of_file);
154
155 /*
156 * i_blocks is not related to (i_size / i_blksize),
157 * but instead 512 byte (2**9) size is required for
158 * calculating num blocks.
159 */
160 inode->i_blocks = (512 - 1 + num_of_bytes) >> 9;
161 }
162 spin_unlock(&inode->i_lock);
163} 195}
164 196
165
166/* 197/*
167 * Needed to setup inode data for the directory which is the 198 * Fill a cifs_fattr struct with fake inode info.
168 * junction to the new submount (ie to setup the fake directory 199 *
169 * which represents a DFS referral) 200 * Needed to setup cifs_fattr data for the directory which is the
201 * junction to the new submount (ie to setup the fake directory
202 * which represents a DFS referral).
170 */ 203 */
171static void fill_fake_finddataunix(FILE_UNIX_BASIC_INFO *pfnd_dat, 204void
172 struct super_block *sb) 205cifs_create_dfs_fattr(struct cifs_fattr *fattr, struct super_block *sb)
173{ 206{
174 struct inode *pinode = NULL; 207 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
175
176 memset(pfnd_dat, 0, sizeof(FILE_UNIX_BASIC_INFO));
177 208
178/* __le64 pfnd_dat->EndOfFile = cpu_to_le64(0); 209 cFYI(1, ("creating fake fattr for DFS referral"));
179 __le64 pfnd_dat->NumOfBytes = cpu_to_le64(0); 210
180 __u64 UniqueId = 0; */ 211 memset(fattr, 0, sizeof(*fattr));
181 pfnd_dat->LastStatusChange = 212 fattr->cf_mode = S_IFDIR | S_IXUGO | S_IRWXU;
182 cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); 213 fattr->cf_uid = cifs_sb->mnt_uid;
183 pfnd_dat->LastAccessTime = 214 fattr->cf_gid = cifs_sb->mnt_gid;
184 cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); 215 fattr->cf_atime = CURRENT_TIME;
185 pfnd_dat->LastModificationTime = 216 fattr->cf_ctime = CURRENT_TIME;
186 cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); 217 fattr->cf_mtime = CURRENT_TIME;
187 pfnd_dat->Type = cpu_to_le32(UNIX_DIR); 218 fattr->cf_nlink = 2;
188 pfnd_dat->Permissions = cpu_to_le64(S_IXUGO | S_IRWXU); 219 fattr->cf_flags |= CIFS_FATTR_DFS_REFERRAL;
189 pfnd_dat->Nlinks = cpu_to_le64(2);
190 if (sb->s_root)
191 pinode = sb->s_root->d_inode;
192 if (pinode == NULL)
193 return;
194
195 /* fill in default values for the remaining based on root
196 inode since we can not query the server for this inode info */
197 pfnd_dat->DevMajor = cpu_to_le64(MAJOR(pinode->i_rdev));
198 pfnd_dat->DevMinor = cpu_to_le64(MINOR(pinode->i_rdev));
199 pfnd_dat->Uid = cpu_to_le64(pinode->i_uid);
200 pfnd_dat->Gid = cpu_to_le64(pinode->i_gid);
201} 220}
202 221
203/** 222/**
@@ -244,66 +263,42 @@ cifs_new_inode(struct super_block *sb, __u64 *inum)
244} 263}
245 264
246int cifs_get_inode_info_unix(struct inode **pinode, 265int cifs_get_inode_info_unix(struct inode **pinode,
247 const unsigned char *full_path, struct super_block *sb, int xid) 266 const unsigned char *full_path,
267 struct super_block *sb, int xid)
248{ 268{
249 int rc = 0; 269 int rc;
250 FILE_UNIX_BASIC_INFO find_data; 270 FILE_UNIX_BASIC_INFO find_data;
251 struct cifsTconInfo *pTcon; 271 struct cifs_fattr fattr;
252 struct inode *inode; 272 struct cifsTconInfo *tcon;
253 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 273 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
254 bool is_dfs_referral = false;
255 struct cifsInodeInfo *cifsInfo;
256 __u64 num_of_bytes;
257 __u64 end_of_file;
258 274
259 pTcon = cifs_sb->tcon; 275 tcon = cifs_sb->tcon;
260 cFYI(1, ("Getting info on %s", full_path)); 276 cFYI(1, ("Getting info on %s", full_path));
261 277
262 /* could have done a find first instead but this returns more info */ 278 /* could have done a find first instead but this returns more info */
263 rc = CIFSSMBUnixQPathInfo(xid, pTcon, full_path, &find_data, 279 rc = CIFSSMBUnixQPathInfo(xid, tcon, full_path, &find_data,
264 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 280 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
265 CIFS_MOUNT_MAP_SPECIAL_CHR); 281 CIFS_MOUNT_MAP_SPECIAL_CHR);
266 if (rc == -EREMOTE && !is_dfs_referral) {
267 is_dfs_referral = true;
268 cFYI(DBG2, ("DFS ref"));
269 /* for DFS, server does not give us real inode data */
270 fill_fake_finddataunix(&find_data, sb);
271 rc = 0;
272 } else if (rc)
273 goto cgiiu_exit;
274 282
275 num_of_bytes = le64_to_cpu(find_data.NumOfBytes); 283 if (!rc) {
276 end_of_file = le64_to_cpu(find_data.EndOfFile); 284 cifs_unix_basic_to_fattr(&fattr, &find_data, cifs_sb);
285 } else if (rc == -EREMOTE) {
286 cifs_create_dfs_fattr(&fattr, sb);
287 rc = 0;
288 } else {
289 return rc;
290 }
277 291
278 /* get new inode */
279 if (*pinode == NULL) { 292 if (*pinode == NULL) {
280 __u64 unique_id = le64_to_cpu(find_data.UniqueId); 293 /* get new inode */
281 *pinode = cifs_new_inode(sb, &unique_id); 294 *pinode = cifs_iget(sb, &fattr);
282 if (*pinode == NULL) { 295 if (!*pinode)
283 rc = -ENOMEM; 296 rc = -ENOMEM;
284 goto cgiiu_exit; 297 } else {
285 } 298 /* we already have inode, update it */
299 cifs_fattr_to_inode(*pinode, &fattr);
286 } 300 }
287 301
288 inode = *pinode;
289 cifsInfo = CIFS_I(inode);
290
291 cFYI(1, ("Old time %ld", cifsInfo->time));
292 cifsInfo->time = jiffies;
293 cFYI(1, ("New time %ld", cifsInfo->time));
294 /* this is ok to set on every inode revalidate */
295 atomic_set(&cifsInfo->inUse, 1);
296
297 cifs_unix_info_to_inode(inode, &find_data, 0);
298
299 if (num_of_bytes < end_of_file)
300 cFYI(1, ("allocation size less than end of file"));
301 cFYI(1, ("Size %ld and blocks %llu",
302 (unsigned long) inode->i_size,
303 (unsigned long long)inode->i_blocks));
304
305 cifs_set_ops(inode, is_dfs_referral);
306cgiiu_exit:
307 return rc; 302 return rc;
308} 303}
309 304
@@ -695,33 +690,85 @@ char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb)
695 return full_path; 690 return full_path;
696} 691}
697 692
693static int
694cifs_find_inode(struct inode *inode, void *opaque)
695{
696 struct cifs_fattr *fattr = (struct cifs_fattr *) opaque;
697
698 if (CIFS_I(inode)->uniqueid != fattr->cf_uniqueid)
699 return 0;
700
701 return 1;
702}
703
704static int
705cifs_init_inode(struct inode *inode, void *opaque)
706{
707 struct cifs_fattr *fattr = (struct cifs_fattr *) opaque;
708
709 CIFS_I(inode)->uniqueid = fattr->cf_uniqueid;
710 return 0;
711}
712
713/* Given fattrs, get a corresponding inode */
714struct inode *
715cifs_iget(struct super_block *sb, struct cifs_fattr *fattr)
716{
717 unsigned long hash;
718 struct inode *inode;
719
720 cFYI(1, ("looking for uniqueid=%llu", fattr->cf_uniqueid));
721
722 /* hash down to 32-bits on 32-bit arch */
723 hash = cifs_uniqueid_to_ino_t(fattr->cf_uniqueid);
724
725 inode = iget5_locked(sb, hash, cifs_find_inode, cifs_init_inode, fattr);
726
727 /* we have fattrs in hand, update the inode */
728 if (inode) {
729 cifs_fattr_to_inode(inode, fattr);
730 if (sb->s_flags & MS_NOATIME)
731 inode->i_flags |= S_NOATIME | S_NOCMTIME;
732 if (inode->i_state & I_NEW) {
733 inode->i_ino = hash;
734 unlock_new_inode(inode);
735 }
736 }
737
738 return inode;
739}
740
698/* gets root inode */ 741/* gets root inode */
699struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino) 742struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino)
700{ 743{
701 int xid; 744 int xid;
702 struct cifs_sb_info *cifs_sb; 745 struct cifs_sb_info *cifs_sb;
703 struct inode *inode; 746 struct inode *inode = NULL;
704 long rc; 747 long rc;
705 char *full_path; 748 char *full_path;
706 749
707 inode = iget_locked(sb, ino); 750 cifs_sb = CIFS_SB(sb);
708 if (!inode)
709 return ERR_PTR(-ENOMEM);
710 if (!(inode->i_state & I_NEW))
711 return inode;
712
713 cifs_sb = CIFS_SB(inode->i_sb);
714 full_path = cifs_build_path_to_root(cifs_sb); 751 full_path = cifs_build_path_to_root(cifs_sb);
715 if (full_path == NULL) 752 if (full_path == NULL)
716 return ERR_PTR(-ENOMEM); 753 return ERR_PTR(-ENOMEM);
717 754
718 xid = GetXid(); 755 xid = GetXid();
719 if (cifs_sb->tcon->unix_ext) 756 if (cifs_sb->tcon->unix_ext) {
720 rc = cifs_get_inode_info_unix(&inode, full_path, inode->i_sb, 757 rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
721 xid); 758 if (!inode)
722 else 759 return ERR_PTR(-ENOMEM);
760 } else {
761 inode = iget_locked(sb, ino);
762 if (!inode)
763 return ERR_PTR(-ENOMEM);
764 if (!(inode->i_state & I_NEW))
765 return inode;
766
723 rc = cifs_get_inode_info(&inode, full_path, NULL, inode->i_sb, 767 rc = cifs_get_inode_info(&inode, full_path, NULL, inode->i_sb,
724 xid, NULL); 768 xid, NULL);
769 unlock_new_inode(inode);
770 }
771
725 if (rc && cifs_sb->tcon->ipc) { 772 if (rc && cifs_sb->tcon->ipc) {
726 cFYI(1, ("ipc connection - fake read inode")); 773 cFYI(1, ("ipc connection - fake read inode"));
727 inode->i_mode |= S_IFDIR; 774 inode->i_mode |= S_IFDIR;
@@ -737,7 +784,6 @@ struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino)
737 return ERR_PTR(rc); 784 return ERR_PTR(rc);
738 } 785 }
739 786
740 unlock_new_inode(inode);
741 787
742 kfree(full_path); 788 kfree(full_path);
743 /* can not call macro FreeXid here since in a void func 789 /* can not call macro FreeXid here since in a void func
@@ -1063,44 +1109,6 @@ out_reval:
1063 return rc; 1109 return rc;
1064} 1110}
1065 1111
1066void posix_fill_in_inode(struct inode *tmp_inode,
1067 FILE_UNIX_BASIC_INFO *pData, int isNewInode)
1068{
1069 struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode);
1070 loff_t local_size;
1071 struct timespec local_mtime;
1072
1073 cifsInfo->time = jiffies;
1074 atomic_inc(&cifsInfo->inUse);
1075
1076 /* save mtime and size */
1077 local_mtime = tmp_inode->i_mtime;
1078 local_size = tmp_inode->i_size;
1079
1080 cifs_unix_info_to_inode(tmp_inode, pData, 1);
1081 cifs_set_ops(tmp_inode, false);
1082
1083 if (!S_ISREG(tmp_inode->i_mode))
1084 return;
1085
1086 /*
1087 * No sense invalidating pages for new inode
1088 * since we we have not started caching
1089 * readahead file data yet.
1090 */
1091 if (isNewInode)
1092 return;
1093
1094 if (timespec_equal(&tmp_inode->i_mtime, &local_mtime) &&
1095 (local_size == tmp_inode->i_size)) {
1096 cFYI(1, ("inode exists but unchanged"));
1097 } else {
1098 /* file may have changed on server */
1099 cFYI(1, ("invalidate inode, readdir detected change"));
1100 invalidate_remote_inode(tmp_inode);
1101 }
1102}
1103
1104int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) 1112int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
1105{ 1113{
1106 int rc = 0, tmprc; 1114 int rc = 0, tmprc;
@@ -1109,6 +1117,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
1109 struct cifsTconInfo *pTcon; 1117 struct cifsTconInfo *pTcon;
1110 char *full_path = NULL; 1118 char *full_path = NULL;
1111 struct inode *newinode = NULL; 1119 struct inode *newinode = NULL;
1120 struct cifs_fattr fattr;
1112 1121
1113 cFYI(1, ("In cifs_mkdir, mode = 0x%x inode = 0x%p", mode, inode)); 1122 cFYI(1, ("In cifs_mkdir, mode = 0x%x inode = 0x%p", mode, inode));
1114 1123
@@ -1148,7 +1157,6 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
1148 cFYI(1, ("posix mkdir returned 0x%x", rc)); 1157 cFYI(1, ("posix mkdir returned 0x%x", rc));
1149 d_drop(direntry); 1158 d_drop(direntry);
1150 } else { 1159 } else {
1151 __u64 unique_id;
1152 if (pInfo->Type == cpu_to_le32(-1)) { 1160 if (pInfo->Type == cpu_to_le32(-1)) {
1153 /* no return info, go query for it */ 1161 /* no return info, go query for it */
1154 kfree(pInfo); 1162 kfree(pInfo);
@@ -1162,20 +1170,15 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
1162 else 1170 else
1163 direntry->d_op = &cifs_dentry_ops; 1171 direntry->d_op = &cifs_dentry_ops;
1164 1172
1165 unique_id = le64_to_cpu(pInfo->UniqueId); 1173 cifs_unix_basic_to_fattr(&fattr, pInfo, cifs_sb);
1166 newinode = cifs_new_inode(inode->i_sb, &unique_id); 1174 newinode = cifs_iget(inode->i_sb, &fattr);
1167 if (newinode == NULL) { 1175 if (!newinode) {
1168 kfree(pInfo); 1176 kfree(pInfo);
1169 goto mkdir_get_info; 1177 goto mkdir_get_info;
1170 } 1178 }
1171 1179
1172 newinode->i_nlink = 2;
1173 d_instantiate(direntry, newinode); 1180 d_instantiate(direntry, newinode);
1174 1181
1175 /* we already checked in POSIXCreate whether
1176 frame was long enough */
1177 posix_fill_in_inode(direntry->d_inode,
1178 pInfo, 1 /* NewInode */);
1179#ifdef CONFIG_CIFS_DEBUG2 1182#ifdef CONFIG_CIFS_DEBUG2
1180 cFYI(1, ("instantiated dentry %p %s to inode %p", 1183 cFYI(1, ("instantiated dentry %p %s to inode %p",
1181 direntry, direntry->d_name.name, newinode)); 1184 direntry, direntry->d_name.name, newinode));
@@ -1622,6 +1625,7 @@ int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry,
1622 if (!err) { 1625 if (!err) {
1623 generic_fillattr(dentry->d_inode, stat); 1626 generic_fillattr(dentry->d_inode, stat);
1624 stat->blksize = CIFS_MAX_MSGSIZE; 1627 stat->blksize = CIFS_MAX_MSGSIZE;
1628 stat->ino = CIFS_I(dentry->d_inode)->uniqueid;
1625 } 1629 }
1626 return err; 1630 return err;
1627} 1631}
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index 86d0055dc529..231aa6953f83 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -63,6 +63,55 @@ static inline void dump_cifs_file_struct(struct file *file, char *label)
63} 63}
64#endif /* DEBUG2 */ 64#endif /* DEBUG2 */
65 65
66/*
67 * Find the dentry that matches "name". If there isn't one, create one. If it's
68 * a negative dentry or the uniqueid changed, then drop it and recreate it.
69 */
70static struct dentry *
71cifs_readdir_lookup(struct dentry *parent, struct qstr *name,
72 struct cifs_fattr *fattr)
73{
74 struct dentry *dentry, *alias;
75 struct inode *inode;
76 struct super_block *sb = parent->d_inode->i_sb;
77
78 cFYI(1, ("For %s", name->name));
79
80 dentry = d_lookup(parent, name);
81 if (dentry) {
82 /* FIXME: check for inode number changes? */
83 if (dentry->d_inode != NULL)
84 return dentry;
85 d_drop(dentry);
86 dput(dentry);
87 }
88
89 dentry = d_alloc(parent, name);
90 if (dentry == NULL)
91 return NULL;
92
93 inode = cifs_iget(sb, fattr);
94 if (!inode) {
95 dput(dentry);
96 return NULL;
97 }
98
99 if (CIFS_SB(sb)->tcon->nocase)
100 dentry->d_op = &cifs_ci_dentry_ops;
101 else
102 dentry->d_op = &cifs_dentry_ops;
103
104 alias = d_materialise_unique(dentry, inode);
105 if (alias != NULL) {
106 dput(dentry);
107 if (IS_ERR(alias))
108 return NULL;
109 dentry = alias;
110 }
111
112 return dentry;
113}
114
66/* Returns 1 if new inode created, 2 if both dentry and inode were */ 115/* Returns 1 if new inode created, 2 if both dentry and inode were */
67/* Might check in the future if inode number changed so we can rehash inode */ 116/* Might check in the future if inode number changed so we can rehash inode */
68static int 117static int
@@ -76,7 +125,6 @@ construct_dentry(struct qstr *qstring, struct file *file,
76 125
77 cFYI(1, ("For %s", qstring->name)); 126 cFYI(1, ("For %s", qstring->name));
78 127
79 qstring->hash = full_name_hash(qstring->name, qstring->len);
80 tmp_dentry = d_lookup(file->f_path.dentry, qstring); 128 tmp_dentry = d_lookup(file->f_path.dentry, qstring);
81 if (tmp_dentry) { 129 if (tmp_dentry) {
82 /* BB: overwrite old name? i.e. tmp_dentry->d_name and 130 /* BB: overwrite old name? i.e. tmp_dentry->d_name and
@@ -299,140 +347,6 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
299 } 347 }
300} 348}
301 349
302static void unix_fill_in_inode(struct inode *tmp_inode,
303 FILE_UNIX_INFO *pfindData, unsigned int *pobject_type, int isNewInode)
304{
305 loff_t local_size;
306 struct timespec local_mtime;
307
308 struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode);
309 struct cifs_sb_info *cifs_sb = CIFS_SB(tmp_inode->i_sb);
310
311 __u32 type = le32_to_cpu(pfindData->Type);
312 __u64 num_of_bytes = le64_to_cpu(pfindData->NumOfBytes);
313 __u64 end_of_file = le64_to_cpu(pfindData->EndOfFile);
314 cifsInfo->time = jiffies;
315 atomic_inc(&cifsInfo->inUse);
316
317 /* save mtime and size */
318 local_mtime = tmp_inode->i_mtime;
319 local_size = tmp_inode->i_size;
320
321 tmp_inode->i_atime =
322 cifs_NTtimeToUnix(pfindData->LastAccessTime);
323 tmp_inode->i_mtime =
324 cifs_NTtimeToUnix(pfindData->LastModificationTime);
325 tmp_inode->i_ctime =
326 cifs_NTtimeToUnix(pfindData->LastStatusChange);
327
328 tmp_inode->i_mode = le64_to_cpu(pfindData->Permissions);
329 /* since we set the inode type below we need to mask off type
330 to avoid strange results if bits above were corrupt */
331 tmp_inode->i_mode &= ~S_IFMT;
332 if (type == UNIX_FILE) {
333 *pobject_type = DT_REG;
334 tmp_inode->i_mode |= S_IFREG;
335 } else if (type == UNIX_SYMLINK) {
336 *pobject_type = DT_LNK;
337 tmp_inode->i_mode |= S_IFLNK;
338 } else if (type == UNIX_DIR) {
339 *pobject_type = DT_DIR;
340 tmp_inode->i_mode |= S_IFDIR;
341 } else if (type == UNIX_CHARDEV) {
342 *pobject_type = DT_CHR;
343 tmp_inode->i_mode |= S_IFCHR;
344 tmp_inode->i_rdev = MKDEV(le64_to_cpu(pfindData->DevMajor),
345 le64_to_cpu(pfindData->DevMinor) & MINORMASK);
346 } else if (type == UNIX_BLOCKDEV) {
347 *pobject_type = DT_BLK;
348 tmp_inode->i_mode |= S_IFBLK;
349 tmp_inode->i_rdev = MKDEV(le64_to_cpu(pfindData->DevMajor),
350 le64_to_cpu(pfindData->DevMinor) & MINORMASK);
351 } else if (type == UNIX_FIFO) {
352 *pobject_type = DT_FIFO;
353 tmp_inode->i_mode |= S_IFIFO;
354 } else if (type == UNIX_SOCKET) {
355 *pobject_type = DT_SOCK;
356 tmp_inode->i_mode |= S_IFSOCK;
357 } else {
358 /* safest to just call it a file */
359 *pobject_type = DT_REG;
360 tmp_inode->i_mode |= S_IFREG;
361 cFYI(1, ("unknown inode type %d", type));
362 }
363
364 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)
365 tmp_inode->i_uid = cifs_sb->mnt_uid;
366 else
367 tmp_inode->i_uid = le64_to_cpu(pfindData->Uid);
368 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)
369 tmp_inode->i_gid = cifs_sb->mnt_gid;
370 else
371 tmp_inode->i_gid = le64_to_cpu(pfindData->Gid);
372 tmp_inode->i_nlink = le64_to_cpu(pfindData->Nlinks);
373
374 cifsInfo->server_eof = end_of_file;
375 spin_lock(&tmp_inode->i_lock);
376 if (is_size_safe_to_change(cifsInfo, end_of_file)) {
377 /* can not safely change the file size here if the
378 client is writing to it due to potential races */
379 i_size_write(tmp_inode, end_of_file);
380
381 /* 512 bytes (2**9) is the fake blocksize that must be used */
382 /* for this calculation, not the real blocksize */
383 tmp_inode->i_blocks = (512 - 1 + num_of_bytes) >> 9;
384 }
385 spin_unlock(&tmp_inode->i_lock);
386
387 if (S_ISREG(tmp_inode->i_mode)) {
388 cFYI(1, ("File inode"));
389 tmp_inode->i_op = &cifs_file_inode_ops;
390
391 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
392 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
393 tmp_inode->i_fop = &cifs_file_direct_nobrl_ops;
394 else
395 tmp_inode->i_fop = &cifs_file_direct_ops;
396 } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
397 tmp_inode->i_fop = &cifs_file_nobrl_ops;
398 else
399 tmp_inode->i_fop = &cifs_file_ops;
400
401 if ((cifs_sb->tcon) && (cifs_sb->tcon->ses) &&
402 (cifs_sb->tcon->ses->server->maxBuf <
403 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE))
404 tmp_inode->i_data.a_ops = &cifs_addr_ops_smallbuf;
405 else
406 tmp_inode->i_data.a_ops = &cifs_addr_ops;
407
408 if (isNewInode)
409 return; /* No sense invalidating pages for new inode
410 since we have not started caching readahead
411 file data for it yet */
412
413 if (timespec_equal(&tmp_inode->i_mtime, &local_mtime) &&
414 (local_size == tmp_inode->i_size)) {
415 cFYI(1, ("inode exists but unchanged"));
416 } else {
417 /* file may have changed on server */
418 cFYI(1, ("invalidate inode, readdir detected change"));
419 invalidate_remote_inode(tmp_inode);
420 }
421 } else if (S_ISDIR(tmp_inode->i_mode)) {
422 cFYI(1, ("Directory inode"));
423 tmp_inode->i_op = &cifs_dir_inode_ops;
424 tmp_inode->i_fop = &cifs_dir_ops;
425 } else if (S_ISLNK(tmp_inode->i_mode)) {
426 cFYI(1, ("Symbolic Link inode"));
427 tmp_inode->i_op = &cifs_symlink_inode_ops;
428/* tmp_inode->i_fop = *//* do not need to set to anything */
429 } else {
430 cFYI(1, ("Special inode"));
431 init_special_inode(tmp_inode, tmp_inode->i_mode,
432 tmp_inode->i_rdev);
433 }
434}
435
436/* BB eventually need to add the following helper function to 350/* BB eventually need to add the following helper function to
437 resolve NT_STATUS_STOPPED_ON_SYMLINK return code when 351 resolve NT_STATUS_STOPPED_ON_SYMLINK return code when
438 we try to do FindFirst on (NTFS) directory symlinks */ 352 we try to do FindFirst on (NTFS) directory symlinks */
@@ -872,7 +786,7 @@ static int cifs_get_name_from_search_buf(struct qstr *pqst,
872 len = strnlen(filename, PATH_MAX); 786 len = strnlen(filename, PATH_MAX);
873 } 787 }
874 788
875 *pinum = le64_to_cpu(pFindData->UniqueId); 789 *pinum = le64_to_cpu(pFindData->basic.UniqueId);
876 } else if (level == SMB_FIND_FILE_DIRECTORY_INFO) { 790 } else if (level == SMB_FIND_FILE_DIRECTORY_INFO) {
877 FILE_DIRECTORY_INFO *pFindData = 791 FILE_DIRECTORY_INFO *pFindData =
878 (FILE_DIRECTORY_INFO *)current_entry; 792 (FILE_DIRECTORY_INFO *)current_entry;
@@ -934,9 +848,11 @@ static int cifs_filldir(char *pfindEntry, struct file *file, filldir_t filldir,
934 struct cifsFileInfo *pCifsF; 848 struct cifsFileInfo *pCifsF;
935 unsigned int obj_type; 849 unsigned int obj_type;
936 __u64 inum; 850 __u64 inum;
851 ino_t ino;
937 struct cifs_sb_info *cifs_sb; 852 struct cifs_sb_info *cifs_sb;
938 struct inode *tmp_inode; 853 struct inode *tmp_inode;
939 struct dentry *tmp_dentry; 854 struct dentry *tmp_dentry;
855 struct cifs_fattr fattr;
940 856
941 /* get filename and len into qstring */ 857 /* get filename and len into qstring */
942 /* get dentry */ 858 /* get dentry */
@@ -967,39 +883,49 @@ static int cifs_filldir(char *pfindEntry, struct file *file, filldir_t filldir,
967 return rc; 883 return rc;
968 884
969 /* only these two infolevels return valid inode numbers */ 885 /* only these two infolevels return valid inode numbers */
970 if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_UNIX || 886 if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_UNIX) {
971 pCifsF->srch_inf.info_level == SMB_FIND_FILE_ID_FULL_DIR_INFO) 887 cifs_unix_basic_to_fattr(&fattr,
972 rc = construct_dentry(&qstring, file, &tmp_inode, &tmp_dentry, 888 &((FILE_UNIX_INFO *) pfindEntry)->basic,
973 &inum); 889 cifs_sb);
974 else 890 tmp_dentry = cifs_readdir_lookup(file->f_dentry, &qstring,
975 rc = construct_dentry(&qstring, file, &tmp_inode, &tmp_dentry, 891 &fattr);
976 NULL); 892 obj_type = fattr.cf_dtype;
893 ino = cifs_uniqueid_to_ino_t(fattr.cf_uniqueid);
894 } else {
895 if (pCifsF->srch_inf.info_level ==
896 SMB_FIND_FILE_ID_FULL_DIR_INFO)
897 rc = construct_dentry(&qstring, file, &tmp_inode,
898 &tmp_dentry, &inum);
899 else
900 rc = construct_dentry(&qstring, file, &tmp_inode,
901 &tmp_dentry, NULL);
977 902
978 if ((tmp_inode == NULL) || (tmp_dentry == NULL)) 903 if ((tmp_inode == NULL) || (tmp_dentry == NULL)) {
979 return -ENOMEM; 904 rc = -ENOMEM;
905 goto out;
906 }
980 907
981 /* we pass in rc below, indicating whether it is a new inode, 908 /* we pass in rc below, indicating whether it is a new inode,
982 so we can figure out whether to invalidate the inode cached 909 * so we can figure out whether to invalidate the inode cached
983 data if the file has changed */ 910 * data if the file has changed
984 if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_UNIX) 911 */
985 unix_fill_in_inode(tmp_inode, 912 if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_INFO_STANDARD)
986 (FILE_UNIX_INFO *)pfindEntry, 913 fill_in_inode(tmp_inode, 0, pfindEntry, &obj_type, rc);
987 &obj_type, rc); 914 else
988 else if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_INFO_STANDARD) 915 fill_in_inode(tmp_inode, 1, pfindEntry, &obj_type, rc);
989 fill_in_inode(tmp_inode, 0 /* old level 1 buffer type */,
990 pfindEntry, &obj_type, rc);
991 else
992 fill_in_inode(tmp_inode, 1 /* NT */, pfindEntry, &obj_type, rc);
993 916
994 if (rc) /* new inode - needs to be tied to dentry */ { 917 /* new inode - needs to be tied to dentry */
995 d_instantiate(tmp_dentry, tmp_inode); 918 if (rc) {
996 if (rc == 2) 919 d_instantiate(tmp_dentry, tmp_inode);
997 d_rehash(tmp_dentry); 920 if (rc == 2)
998 } 921 d_rehash(tmp_dentry);
922 }
999 923
924 ino = cifs_uniqueid_to_ino_t(tmp_inode->i_ino);
925 }
1000 926
1001 rc = filldir(direntry, qstring.name, qstring.len, file->f_pos, 927 rc = filldir(direntry, qstring.name, qstring.len, file->f_pos,
1002 tmp_inode->i_ino, obj_type); 928 ino, obj_type);
1003 if (rc) { 929 if (rc) {
1004 cFYI(1, ("filldir rc = %d", rc)); 930 cFYI(1, ("filldir rc = %d", rc));
1005 /* we can not return filldir errors to the caller 931 /* we can not return filldir errors to the caller
@@ -1008,6 +934,7 @@ static int cifs_filldir(char *pfindEntry, struct file *file, filldir_t filldir,
1008 rc = -EOVERFLOW; 934 rc = -EOVERFLOW;
1009 } 935 }
1010 936
937out:
1011 dput(tmp_dentry); 938 dput(tmp_dentry);
1012 return rc; 939 return rc;
1013} 940}