diff options
author | Jeff Layton <jlayton@redhat.com> | 2009-07-09 01:46:37 -0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2009-07-09 19:05:48 -0400 |
commit | 0b8f18e358384a52c1ed7fa7129c08e7eaf86bb6 (patch) | |
tree | ba5292a38d8910c6b3a3303a3c7f88491e1708af /fs/cifs/readdir.c | |
parent | b77863bfa153e886f9f8faf1a791ba57a36efed0 (diff) |
cifs: convert cifs_get_inode_info and non-posix readdir to use cifs_iget
cifs: convert cifs_get_inode_info and non-posix readdir to use cifs_iget
Rather than allocating an inode and filling it out, have
cifs_get_inode_info fill out a cifs_fattr and call cifs_iget. This means
a pretty hefty reorganization of cifs_get_inode_info.
For the readdir codepath, add a couple of new functions for filling out
cifs_fattr's from different FindFile response infolevels.
Finally, remove cifs_new_inode since there are no more callers.
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/readdir.c')
-rw-r--r-- | fs/cifs/readdir.c | 350 |
1 files changed, 83 insertions, 267 deletions
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 231aa6953f83..f823a4a208a7 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c | |||
@@ -112,239 +112,74 @@ cifs_readdir_lookup(struct dentry *parent, struct qstr *name, | |||
112 | return dentry; | 112 | return dentry; |
113 | } | 113 | } |
114 | 114 | ||
115 | /* Returns 1 if new inode created, 2 if both dentry and inode were */ | 115 | static void |
116 | /* Might check in the future if inode number changed so we can rehash inode */ | 116 | cifs_fill_common_info(struct cifs_fattr *fattr, struct cifs_sb_info *cifs_sb) |
117 | static int | ||
118 | construct_dentry(struct qstr *qstring, struct file *file, | ||
119 | struct inode **ptmp_inode, struct dentry **pnew_dentry, | ||
120 | __u64 *inum) | ||
121 | { | 117 | { |
122 | struct dentry *tmp_dentry = NULL; | 118 | fattr->cf_uid = cifs_sb->mnt_uid; |
123 | struct super_block *sb = file->f_path.dentry->d_sb; | 119 | fattr->cf_gid = cifs_sb->mnt_gid; |
124 | int rc = 0; | ||
125 | 120 | ||
126 | cFYI(1, ("For %s", qstring->name)); | 121 | if (fattr->cf_cifsattrs & ATTR_DIRECTORY) { |
127 | 122 | fattr->cf_mode = S_IFDIR | cifs_sb->mnt_dir_mode; | |
128 | tmp_dentry = d_lookup(file->f_path.dentry, qstring); | 123 | fattr->cf_dtype = DT_DIR; |
129 | if (tmp_dentry) { | ||
130 | /* BB: overwrite old name? i.e. tmp_dentry->d_name and | ||
131 | * tmp_dentry->d_name.len?? | ||
132 | */ | ||
133 | cFYI(0, ("existing dentry with inode 0x%p", | ||
134 | tmp_dentry->d_inode)); | ||
135 | *ptmp_inode = tmp_dentry->d_inode; | ||
136 | if (*ptmp_inode == NULL) { | ||
137 | *ptmp_inode = cifs_new_inode(sb, inum); | ||
138 | if (*ptmp_inode == NULL) | ||
139 | return rc; | ||
140 | rc = 1; | ||
141 | } | ||
142 | } else { | 124 | } else { |
143 | tmp_dentry = d_alloc(file->f_path.dentry, qstring); | 125 | fattr->cf_mode = S_IFREG | cifs_sb->mnt_file_mode; |
144 | if (tmp_dentry == NULL) { | 126 | fattr->cf_dtype = DT_REG; |
145 | cERROR(1, ("Failed allocating dentry")); | ||
146 | *ptmp_inode = NULL; | ||
147 | return rc; | ||
148 | } | ||
149 | |||
150 | if (CIFS_SB(sb)->tcon->nocase) | ||
151 | tmp_dentry->d_op = &cifs_ci_dentry_ops; | ||
152 | else | ||
153 | tmp_dentry->d_op = &cifs_dentry_ops; | ||
154 | |||
155 | *ptmp_inode = cifs_new_inode(sb, inum); | ||
156 | if (*ptmp_inode == NULL) | ||
157 | return rc; | ||
158 | rc = 2; | ||
159 | } | ||
160 | |||
161 | tmp_dentry->d_time = jiffies; | ||
162 | *pnew_dentry = tmp_dentry; | ||
163 | return rc; | ||
164 | } | ||
165 | |||
166 | static void fill_in_inode(struct inode *tmp_inode, int new_buf_type, | ||
167 | char *buf, unsigned int *pobject_type, int isNewInode) | ||
168 | { | ||
169 | loff_t local_size; | ||
170 | struct timespec local_mtime; | ||
171 | |||
172 | struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode); | ||
173 | struct cifs_sb_info *cifs_sb = CIFS_SB(tmp_inode->i_sb); | ||
174 | __u32 attr; | ||
175 | __u64 allocation_size; | ||
176 | __u64 end_of_file; | ||
177 | umode_t default_mode; | ||
178 | |||
179 | /* save mtime and size */ | ||
180 | local_mtime = tmp_inode->i_mtime; | ||
181 | local_size = tmp_inode->i_size; | ||
182 | |||
183 | if (new_buf_type) { | ||
184 | FILE_DIRECTORY_INFO *pfindData = (FILE_DIRECTORY_INFO *)buf; | ||
185 | |||
186 | attr = le32_to_cpu(pfindData->ExtFileAttributes); | ||
187 | allocation_size = le64_to_cpu(pfindData->AllocationSize); | ||
188 | end_of_file = le64_to_cpu(pfindData->EndOfFile); | ||
189 | tmp_inode->i_atime = | ||
190 | cifs_NTtimeToUnix(pfindData->LastAccessTime); | ||
191 | tmp_inode->i_mtime = | ||
192 | cifs_NTtimeToUnix(pfindData->LastWriteTime); | ||
193 | tmp_inode->i_ctime = | ||
194 | cifs_NTtimeToUnix(pfindData->ChangeTime); | ||
195 | } else { /* legacy, OS2 and DOS style */ | ||
196 | int offset = cifs_sb->tcon->ses->server->timeAdj; | ||
197 | FIND_FILE_STANDARD_INFO *pfindData = | ||
198 | (FIND_FILE_STANDARD_INFO *)buf; | ||
199 | |||
200 | tmp_inode->i_mtime = cnvrtDosUnixTm(pfindData->LastWriteDate, | ||
201 | pfindData->LastWriteTime, | ||
202 | offset); | ||
203 | tmp_inode->i_atime = cnvrtDosUnixTm(pfindData->LastAccessDate, | ||
204 | pfindData->LastAccessTime, | ||
205 | offset); | ||
206 | tmp_inode->i_ctime = cnvrtDosUnixTm(pfindData->LastWriteDate, | ||
207 | pfindData->LastWriteTime, | ||
208 | offset); | ||
209 | attr = le16_to_cpu(pfindData->Attributes); | ||
210 | allocation_size = le32_to_cpu(pfindData->AllocationSize); | ||
211 | end_of_file = le32_to_cpu(pfindData->DataSize); | ||
212 | } | ||
213 | |||
214 | /* Linux can not store file creation time unfortunately so ignore it */ | ||
215 | |||
216 | cifsInfo->cifsAttrs = attr; | ||
217 | #ifdef CONFIG_CIFS_EXPERIMENTAL | ||
218 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { | ||
219 | /* get more accurate mode via ACL - so force inode refresh */ | ||
220 | cifsInfo->time = 0; | ||
221 | } else | ||
222 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ | ||
223 | cifsInfo->time = jiffies; | ||
224 | |||
225 | /* treat dos attribute of read-only as read-only mode bit e.g. 555? */ | ||
226 | /* 2767 perms - indicate mandatory locking */ | ||
227 | /* BB fill in uid and gid here? with help from winbind? | ||
228 | or retrieve from NTFS stream extended attribute */ | ||
229 | if (atomic_read(&cifsInfo->inUse) == 0) { | ||
230 | tmp_inode->i_uid = cifs_sb->mnt_uid; | ||
231 | tmp_inode->i_gid = cifs_sb->mnt_gid; | ||
232 | } | 127 | } |
233 | 128 | ||
234 | if (attr & ATTR_DIRECTORY) | 129 | if (fattr->cf_cifsattrs & ATTR_READONLY) |
235 | default_mode = cifs_sb->mnt_dir_mode; | 130 | fattr->cf_mode &= ~S_IWUGO; |
236 | else | ||
237 | default_mode = cifs_sb->mnt_file_mode; | ||
238 | |||
239 | /* set initial permissions */ | ||
240 | if ((atomic_read(&cifsInfo->inUse) == 0) || | ||
241 | (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) == 0) | ||
242 | tmp_inode->i_mode = default_mode; | ||
243 | else { | ||
244 | /* just reenable write bits if !ATTR_READONLY */ | ||
245 | if ((tmp_inode->i_mode & S_IWUGO) == 0 && | ||
246 | (attr & ATTR_READONLY) == 0) | ||
247 | tmp_inode->i_mode |= (S_IWUGO & default_mode); | ||
248 | |||
249 | tmp_inode->i_mode &= ~S_IFMT; | ||
250 | } | ||
251 | |||
252 | /* clear write bits if ATTR_READONLY is set */ | ||
253 | if (attr & ATTR_READONLY) | ||
254 | tmp_inode->i_mode &= ~S_IWUGO; | ||
255 | 131 | ||
256 | /* set inode type */ | 132 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL && |
257 | if ((attr & ATTR_SYSTEM) && | 133 | fattr->cf_cifsattrs & ATTR_SYSTEM) { |
258 | (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)) { | 134 | if (fattr->cf_eof == 0) { |
259 | if (end_of_file == 0) { | 135 | fattr->cf_mode &= ~S_IFMT; |
260 | tmp_inode->i_mode |= S_IFIFO; | 136 | fattr->cf_mode |= S_IFIFO; |
261 | *pobject_type = DT_FIFO; | 137 | fattr->cf_dtype = DT_FIFO; |
262 | } else { | 138 | } else { |
263 | /* | 139 | /* |
264 | * trying to get the type can be slow, so just call | 140 | * trying to get the type and mode via SFU can be slow, |
265 | * this a regular file for now, and mark for reval | 141 | * so just call those regular files for now, and mark |
142 | * for reval | ||
266 | */ | 143 | */ |
267 | tmp_inode->i_mode |= S_IFREG; | 144 | fattr->cf_flags |= CIFS_FATTR_NEED_REVAL; |
268 | *pobject_type = DT_REG; | ||
269 | cifsInfo->time = 0; | ||
270 | } | ||
271 | } else { | ||
272 | if (attr & ATTR_DIRECTORY) { | ||
273 | tmp_inode->i_mode |= S_IFDIR; | ||
274 | *pobject_type = DT_DIR; | ||
275 | } else { | ||
276 | tmp_inode->i_mode |= S_IFREG; | ||
277 | *pobject_type = DT_REG; | ||
278 | } | 145 | } |
279 | } | 146 | } |
147 | } | ||
280 | 148 | ||
281 | /* can not fill in nlink here as in qpathinfo version and Unx search */ | 149 | void |
282 | if (atomic_read(&cifsInfo->inUse) == 0) | 150 | cifs_dir_info_to_fattr(struct cifs_fattr *fattr, FILE_DIRECTORY_INFO *info, |
283 | atomic_set(&cifsInfo->inUse, 1); | 151 | struct cifs_sb_info *cifs_sb) |
152 | { | ||
153 | memset(fattr, 0, sizeof(*fattr)); | ||
154 | fattr->cf_cifsattrs = le32_to_cpu(info->ExtFileAttributes); | ||
155 | fattr->cf_eof = le64_to_cpu(info->EndOfFile); | ||
156 | fattr->cf_bytes = le64_to_cpu(info->AllocationSize); | ||
157 | fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime); | ||
158 | fattr->cf_ctime = cifs_NTtimeToUnix(info->ChangeTime); | ||
159 | fattr->cf_mtime = cifs_NTtimeToUnix(info->LastWriteTime); | ||
160 | |||
161 | cifs_fill_common_info(fattr, cifs_sb); | ||
162 | } | ||
284 | 163 | ||
285 | cifsInfo->server_eof = end_of_file; | 164 | void |
286 | spin_lock(&tmp_inode->i_lock); | 165 | cifs_std_info_to_fattr(struct cifs_fattr *fattr, FIND_FILE_STANDARD_INFO *info, |
287 | if (is_size_safe_to_change(cifsInfo, end_of_file)) { | 166 | struct cifs_sb_info *cifs_sb) |
288 | /* can not safely change the file size here if the | 167 | { |
289 | client is writing to it due to potential races */ | 168 | int offset = cifs_sb->tcon->ses->server->timeAdj; |
290 | i_size_write(tmp_inode, end_of_file); | ||
291 | 169 | ||
292 | /* 512 bytes (2**9) is the fake blocksize that must be used */ | 170 | memset(fattr, 0, sizeof(*fattr)); |
293 | /* for this calculation, even though the reported blocksize is larger */ | 171 | fattr->cf_atime = cnvrtDosUnixTm(info->LastAccessDate, |
294 | tmp_inode->i_blocks = (512 - 1 + allocation_size) >> 9; | 172 | info->LastAccessTime, offset); |
295 | } | 173 | fattr->cf_ctime = cnvrtDosUnixTm(info->LastWriteDate, |
296 | spin_unlock(&tmp_inode->i_lock); | 174 | info->LastWriteTime, offset); |
297 | 175 | fattr->cf_mtime = cnvrtDosUnixTm(info->LastWriteDate, | |
298 | if (allocation_size < end_of_file) | 176 | info->LastWriteTime, offset); |
299 | cFYI(1, ("May be sparse file, allocation less than file size")); | 177 | |
300 | cFYI(1, ("File Size %ld and blocks %llu", | 178 | fattr->cf_cifsattrs = le16_to_cpu(info->Attributes); |
301 | (unsigned long)tmp_inode->i_size, | 179 | fattr->cf_bytes = le32_to_cpu(info->AllocationSize); |
302 | (unsigned long long)tmp_inode->i_blocks)); | 180 | fattr->cf_eof = le32_to_cpu(info->DataSize); |
303 | if (S_ISREG(tmp_inode->i_mode)) { | 181 | |
304 | cFYI(1, ("File inode")); | 182 | cifs_fill_common_info(fattr, cifs_sb); |
305 | tmp_inode->i_op = &cifs_file_inode_ops; | ||
306 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { | ||
307 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) | ||
308 | tmp_inode->i_fop = &cifs_file_direct_nobrl_ops; | ||
309 | else | ||
310 | tmp_inode->i_fop = &cifs_file_direct_ops; | ||
311 | } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) | ||
312 | tmp_inode->i_fop = &cifs_file_nobrl_ops; | ||
313 | else | ||
314 | tmp_inode->i_fop = &cifs_file_ops; | ||
315 | |||
316 | if ((cifs_sb->tcon) && (cifs_sb->tcon->ses) && | ||
317 | (cifs_sb->tcon->ses->server->maxBuf < | ||
318 | PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE)) | ||
319 | tmp_inode->i_data.a_ops = &cifs_addr_ops_smallbuf; | ||
320 | else | ||
321 | tmp_inode->i_data.a_ops = &cifs_addr_ops; | ||
322 | |||
323 | if (isNewInode) | ||
324 | return; /* No sense invalidating pages for new inode | ||
325 | since have not started caching readahead file | ||
326 | data yet */ | ||
327 | |||
328 | if (timespec_equal(&tmp_inode->i_mtime, &local_mtime) && | ||
329 | (local_size == tmp_inode->i_size)) { | ||
330 | cFYI(1, ("inode exists but unchanged")); | ||
331 | } else { | ||
332 | /* file may have changed on server */ | ||
333 | cFYI(1, ("invalidate inode, readdir detected change")); | ||
334 | invalidate_remote_inode(tmp_inode); | ||
335 | } | ||
336 | } else if (S_ISDIR(tmp_inode->i_mode)) { | ||
337 | cFYI(1, ("Directory inode")); | ||
338 | tmp_inode->i_op = &cifs_dir_inode_ops; | ||
339 | tmp_inode->i_fop = &cifs_dir_ops; | ||
340 | } else if (S_ISLNK(tmp_inode->i_mode)) { | ||
341 | cFYI(1, ("Symbolic Link inode")); | ||
342 | tmp_inode->i_op = &cifs_symlink_inode_ops; | ||
343 | } else { | ||
344 | cFYI(1, ("Init special inode")); | ||
345 | init_special_inode(tmp_inode, tmp_inode->i_mode, | ||
346 | tmp_inode->i_rdev); | ||
347 | } | ||
348 | } | 183 | } |
349 | 184 | ||
350 | /* BB eventually need to add the following helper function to | 185 | /* BB eventually need to add the following helper function to |
@@ -846,11 +681,10 @@ static int cifs_filldir(char *pfindEntry, struct file *file, filldir_t filldir, | |||
846 | int rc = 0; | 681 | int rc = 0; |
847 | struct qstr qstring; | 682 | struct qstr qstring; |
848 | struct cifsFileInfo *pCifsF; | 683 | struct cifsFileInfo *pCifsF; |
849 | unsigned int obj_type; | 684 | u64 inum; |
850 | __u64 inum; | ||
851 | ino_t ino; | 685 | ino_t ino; |
686 | struct super_block *sb; | ||
852 | struct cifs_sb_info *cifs_sb; | 687 | struct cifs_sb_info *cifs_sb; |
853 | struct inode *tmp_inode; | ||
854 | struct dentry *tmp_dentry; | 688 | struct dentry *tmp_dentry; |
855 | struct cifs_fattr fattr; | 689 | struct cifs_fattr fattr; |
856 | 690 | ||
@@ -870,71 +704,53 @@ static int cifs_filldir(char *pfindEntry, struct file *file, filldir_t filldir, | |||
870 | if (rc != 0) | 704 | if (rc != 0) |
871 | return 0; | 705 | return 0; |
872 | 706 | ||
873 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); | 707 | sb = file->f_path.dentry->d_sb; |
708 | cifs_sb = CIFS_SB(sb); | ||
874 | 709 | ||
875 | qstring.name = scratch_buf; | 710 | qstring.name = scratch_buf; |
876 | rc = cifs_get_name_from_search_buf(&qstring, pfindEntry, | 711 | rc = cifs_get_name_from_search_buf(&qstring, pfindEntry, |
877 | pCifsF->srch_inf.info_level, | 712 | pCifsF->srch_inf.info_level, |
878 | pCifsF->srch_inf.unicode, cifs_sb, | 713 | pCifsF->srch_inf.unicode, cifs_sb, |
879 | max_len, | 714 | max_len, &inum /* returned */); |
880 | &inum /* returned */); | ||
881 | 715 | ||
882 | if (rc) | 716 | if (rc) |
883 | return rc; | 717 | return rc; |
884 | 718 | ||
885 | /* only these two infolevels return valid inode numbers */ | 719 | if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_UNIX) |
886 | if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_UNIX) { | ||
887 | cifs_unix_basic_to_fattr(&fattr, | 720 | cifs_unix_basic_to_fattr(&fattr, |
888 | &((FILE_UNIX_INFO *) pfindEntry)->basic, | 721 | &((FILE_UNIX_INFO *) pfindEntry)->basic, |
889 | cifs_sb); | 722 | cifs_sb); |
890 | tmp_dentry = cifs_readdir_lookup(file->f_dentry, &qstring, | 723 | else if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_INFO_STANDARD) |
891 | &fattr); | 724 | cifs_std_info_to_fattr(&fattr, (FIND_FILE_STANDARD_INFO *) |
892 | obj_type = fattr.cf_dtype; | 725 | pfindEntry, cifs_sb); |
893 | ino = cifs_uniqueid_to_ino_t(fattr.cf_uniqueid); | 726 | else |
894 | } else { | 727 | cifs_dir_info_to_fattr(&fattr, (FILE_DIRECTORY_INFO *) |
895 | if (pCifsF->srch_inf.info_level == | 728 | pfindEntry, cifs_sb); |
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); | ||
902 | |||
903 | if ((tmp_inode == NULL) || (tmp_dentry == NULL)) { | ||
904 | rc = -ENOMEM; | ||
905 | goto out; | ||
906 | } | ||
907 | |||
908 | /* we pass in rc below, indicating whether it is a new inode, | ||
909 | * so we can figure out whether to invalidate the inode cached | ||
910 | * data if the file has changed | ||
911 | */ | ||
912 | if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_INFO_STANDARD) | ||
913 | fill_in_inode(tmp_inode, 0, pfindEntry, &obj_type, rc); | ||
914 | else | ||
915 | fill_in_inode(tmp_inode, 1, pfindEntry, &obj_type, rc); | ||
916 | 729 | ||
917 | /* new inode - needs to be tied to dentry */ | 730 | /* FIXME: make _to_fattr functions fill this out */ |
918 | if (rc) { | 731 | if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_ID_FULL_DIR_INFO) |
919 | d_instantiate(tmp_dentry, tmp_inode); | 732 | fattr.cf_uniqueid = inum; |
920 | if (rc == 2) | 733 | else |
921 | d_rehash(tmp_dentry); | 734 | fattr.cf_uniqueid = iunique(sb, ROOT_I); |
922 | } | ||
923 | 735 | ||
924 | ino = cifs_uniqueid_to_ino_t(tmp_inode->i_ino); | 736 | ino = cifs_uniqueid_to_ino_t(fattr.cf_uniqueid); |
925 | } | 737 | tmp_dentry = cifs_readdir_lookup(file->f_dentry, &qstring, &fattr); |
926 | 738 | ||
927 | rc = filldir(direntry, qstring.name, qstring.len, file->f_pos, | 739 | rc = filldir(direntry, qstring.name, qstring.len, file->f_pos, |
928 | ino, obj_type); | 740 | ino, fattr.cf_dtype); |
741 | |||
742 | /* | ||
743 | * we can not return filldir errors to the caller since they are | ||
744 | * "normal" when the stat blocksize is too small - we return remapped | ||
745 | * error instead | ||
746 | * | ||
747 | * FIXME: This looks bogus. filldir returns -EOVERFLOW in the above | ||
748 | * case already. Why should we be clobbering other errors from it? | ||
749 | */ | ||
929 | if (rc) { | 750 | if (rc) { |
930 | cFYI(1, ("filldir rc = %d", rc)); | 751 | cFYI(1, ("filldir rc = %d", rc)); |
931 | /* we can not return filldir errors to the caller | ||
932 | since they are "normal" when the stat blocksize | ||
933 | is too small - we return remapped error instead */ | ||
934 | rc = -EOVERFLOW; | 752 | rc = -EOVERFLOW; |
935 | } | 753 | } |
936 | |||
937 | out: | ||
938 | dput(tmp_dentry); | 754 | dput(tmp_dentry); |
939 | return rc; | 755 | return rc; |
940 | } | 756 | } |