blob: 1023d78673fb14b38ba32c793edee92b119053e9 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * fs/cifs/inode.c
3 *
Steve Frenchf19159d2010-04-21 04:12:10 +00004 * Copyright (C) International Business Machines Corp., 2002,2010
Linus Torvalds1da177e2005-04-16 15:20:36 -07005 * Author(s): Steve French (sfrench@us.ibm.com)
6 *
7 * This library is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published
9 * by the Free Software Foundation; either version 2.1 of the License, or
10 * (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
15 * the GNU Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21#include <linux/fs.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070022#include <linux/stat.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090023#include <linux/slab.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070024#include <linux/pagemap.h>
Jeff Layton4f73c7d2014-04-30 09:31:47 -040025#include <linux/freezer.h>
Ingo Molnar174cd4b2017-02-02 19:15:33 +010026#include <linux/sched/signal.h>
Ingo Molnar5dd43ce2017-06-20 12:19:09 +020027#include <linux/wait_bit.h>
Ingo Molnar174cd4b2017-02-02 19:15:33 +010028
Linus Torvalds1da177e2005-04-16 15:20:36 -070029#include <asm/div64.h>
30#include "cifsfs.h"
31#include "cifspdu.h"
32#include "cifsglob.h"
33#include "cifsproto.h"
34#include "cifs_debug.h"
35#include "cifs_fs_sb.h"
Steve French2baa2682014-09-27 02:19:01 -050036#include "cifs_unicode.h"
Suresh Jayaraman9451a9a2010-07-05 18:12:45 +053037#include "fscache.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070038
Christoph Hellwig70eff552008-02-15 20:55:05 +000039
David Howells01c64fe2011-01-14 18:45:47 +000040static void cifs_set_ops(struct inode *inode)
Christoph Hellwig70eff552008-02-15 20:55:05 +000041{
42 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
43
44 switch (inode->i_mode & S_IFMT) {
45 case S_IFREG:
46 inode->i_op = &cifs_file_inode_ops;
47 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
48 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
49 inode->i_fop = &cifs_file_direct_nobrl_ops;
50 else
51 inode->i_fop = &cifs_file_direct_ops;
Pavel Shilovsky8be7e6b2010-12-12 13:11:13 +030052 } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO) {
53 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
54 inode->i_fop = &cifs_file_strict_nobrl_ops;
55 else
56 inode->i_fop = &cifs_file_strict_ops;
Christoph Hellwig70eff552008-02-15 20:55:05 +000057 } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
58 inode->i_fop = &cifs_file_nobrl_ops;
59 else { /* not direct, send byte range locks */
60 inode->i_fop = &cifs_file_ops;
61 }
62
Christoph Hellwig70eff552008-02-15 20:55:05 +000063 /* check if server can support readpages */
Jeff Layton0d424ad2010-09-20 16:01:35 -070064 if (cifs_sb_master_tcon(cifs_sb)->ses->server->maxBuf <
Kirill A. Shutemov09cbfea2016-04-01 15:29:47 +030065 PAGE_SIZE + MAX_CIFS_HDR_SIZE)
Christoph Hellwig70eff552008-02-15 20:55:05 +000066 inode->i_data.a_ops = &cifs_addr_ops_smallbuf;
67 else
68 inode->i_data.a_ops = &cifs_addr_ops;
69 break;
70 case S_IFDIR:
Steve Frenchbc5b6e22008-03-11 21:07:48 +000071#ifdef CONFIG_CIFS_DFS_UPCALL
David Howells01c64fe2011-01-14 18:45:47 +000072 if (IS_AUTOMOUNT(inode)) {
Igor Mammedov79626702008-03-09 03:44:18 +000073 inode->i_op = &cifs_dfs_referral_inode_operations;
74 } else {
Steve Frenchbc5b6e22008-03-11 21:07:48 +000075#else /* NO DFS support, treat as a directory */
76 {
77#endif
Igor Mammedov79626702008-03-09 03:44:18 +000078 inode->i_op = &cifs_dir_inode_ops;
79 inode->i_fop = &cifs_dir_ops;
80 }
Christoph Hellwig70eff552008-02-15 20:55:05 +000081 break;
82 case S_IFLNK:
83 inode->i_op = &cifs_symlink_inode_ops;
84 break;
85 default:
86 init_special_inode(inode, inode->i_mode, inode->i_rdev);
87 break;
88 }
89}
90
Jeff Laytondf2cf172010-02-12 07:44:16 -050091/* check inode attributes against fattr. If they don't match, tag the
92 * inode for cache invalidation
93 */
94static void
95cifs_revalidate_cache(struct inode *inode, struct cifs_fattr *fattr)
96{
97 struct cifsInodeInfo *cifs_i = CIFS_I(inode);
98
Joe Perchesf96637b2013-05-04 22:12:25 -050099 cifs_dbg(FYI, "%s: revalidating inode %llu\n",
100 __func__, cifs_i->uniqueid);
Jeff Laytondf2cf172010-02-12 07:44:16 -0500101
102 if (inode->i_state & I_NEW) {
Joe Perchesf96637b2013-05-04 22:12:25 -0500103 cifs_dbg(FYI, "%s: inode %llu is new\n",
104 __func__, cifs_i->uniqueid);
Jeff Laytondf2cf172010-02-12 07:44:16 -0500105 return;
106 }
107
108 /* don't bother with revalidation if we have an oplock */
Pavel Shilovsky18cceb62013-09-05 13:01:06 +0400109 if (CIFS_CACHE_READ(cifs_i)) {
Joe Perchesf96637b2013-05-04 22:12:25 -0500110 cifs_dbg(FYI, "%s: inode %llu is oplocked\n",
111 __func__, cifs_i->uniqueid);
Jeff Laytondf2cf172010-02-12 07:44:16 -0500112 return;
113 }
114
115 /* revalidate if mtime or size have changed */
Arnd Bergmann95390202018-06-19 17:27:58 +0200116 if (timespec64_equal(&inode->i_mtime, &fattr->cf_mtime) &&
Jeff Laytondf2cf172010-02-12 07:44:16 -0500117 cifs_i->server_eof == fattr->cf_eof) {
Joe Perchesf96637b2013-05-04 22:12:25 -0500118 cifs_dbg(FYI, "%s: inode %llu is unchanged\n",
119 __func__, cifs_i->uniqueid);
Jeff Laytondf2cf172010-02-12 07:44:16 -0500120 return;
121 }
122
Joe Perchesf96637b2013-05-04 22:12:25 -0500123 cifs_dbg(FYI, "%s: invalidating inode %llu mapping\n",
124 __func__, cifs_i->uniqueid);
Jeff Laytonaff8d5c2014-04-30 09:31:45 -0400125 set_bit(CIFS_INO_INVALID_MAPPING, &cifs_i->flags);
Jeff Laytondf2cf172010-02-12 07:44:16 -0500126}
127
Jim McDonough74d290d2013-09-21 10:36:10 -0500128/*
129 * copy nlink to the inode, unless it wasn't provided. Provide
130 * sane values if we don't have an existing one and none was provided
131 */
132static void
133cifs_nlink_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
134{
135 /*
136 * if we're in a situation where we can't trust what we
137 * got from the server (readdir, some non-unix cases)
138 * fake reasonable values
139 */
140 if (fattr->cf_flags & CIFS_FATTR_UNKNOWN_NLINK) {
141 /* only provide fake values on a new inode */
142 if (inode->i_state & I_NEW) {
143 if (fattr->cf_cifsattrs & ATTR_DIRECTORY)
144 set_nlink(inode, 2);
145 else
146 set_nlink(inode, 1);
147 }
148 return;
149 }
150
151 /* we trust the server, so update it */
152 set_nlink(inode, fattr->cf_nlink);
153}
154
Jeff Laytoncc0bad72009-06-25 00:56:52 -0400155/* populate an inode with info from a cifs_fattr struct */
156void
157cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
Christoph Hellwig75f12982008-02-25 20:25:21 +0000158{
Jeff Laytoncc0bad72009-06-25 00:56:52 -0400159 struct cifsInodeInfo *cifs_i = CIFS_I(inode);
Jeff Layton0b8f18e2009-07-09 01:46:37 -0400160 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
Christoph Hellwig75f12982008-02-25 20:25:21 +0000161
Jeff Laytondf2cf172010-02-12 07:44:16 -0500162 cifs_revalidate_cache(inode, fattr);
163
Steve Frenchb7ca6922012-08-03 08:43:01 -0500164 spin_lock(&inode->i_lock);
Steve French9b9c5be2018-09-22 12:07:06 -0500165 /* we do not want atime to be less than mtime, it broke some apps */
166 if (timespec64_compare(&fattr->cf_atime, &fattr->cf_mtime))
167 inode->i_atime = fattr->cf_mtime;
168 else
169 inode->i_atime = fattr->cf_atime;
Arnd Bergmann95390202018-06-19 17:27:58 +0200170 inode->i_mtime = fattr->cf_mtime;
171 inode->i_ctime = fattr->cf_ctime;
Jeff Laytoncc0bad72009-06-25 00:56:52 -0400172 inode->i_rdev = fattr->cf_rdev;
Jim McDonough74d290d2013-09-21 10:36:10 -0500173 cifs_nlink_fattr_to_inode(inode, fattr);
Jeff Laytoncc0bad72009-06-25 00:56:52 -0400174 inode->i_uid = fattr->cf_uid;
175 inode->i_gid = fattr->cf_gid;
176
Jeff Layton0b8f18e2009-07-09 01:46:37 -0400177 /* if dynperm is set, don't clobber existing mode */
178 if (inode->i_state & I_NEW ||
179 !(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM))
180 inode->i_mode = fattr->cf_mode;
181
Jeff Laytoncc0bad72009-06-25 00:56:52 -0400182 cifs_i->cifsAttrs = fattr->cf_cifsattrs;
Jeff Laytoncc0bad72009-06-25 00:56:52 -0400183
Jeff Layton0b8f18e2009-07-09 01:46:37 -0400184 if (fattr->cf_flags & CIFS_FATTR_NEED_REVAL)
185 cifs_i->time = 0;
186 else
187 cifs_i->time = jiffies;
188
Jeff Laytonaff8d5c2014-04-30 09:31:45 -0400189 if (fattr->cf_flags & CIFS_FATTR_DELETE_PENDING)
190 set_bit(CIFS_INO_DELETE_PENDING, &cifs_i->flags);
191 else
192 clear_bit(CIFS_INO_DELETE_PENDING, &cifs_i->flags);
Christoph Hellwig75f12982008-02-25 20:25:21 +0000193
Jeff Layton835a36c2010-02-10 16:21:33 -0500194 cifs_i->server_eof = fattr->cf_eof;
Christoph Hellwig75f12982008-02-25 20:25:21 +0000195 /*
Jeff Laytoncc0bad72009-06-25 00:56:52 -0400196 * Can't safely change the file size here if the client is writing to
197 * it due to potential races.
Christoph Hellwig75f12982008-02-25 20:25:21 +0000198 */
Jeff Laytoncc0bad72009-06-25 00:56:52 -0400199 if (is_size_safe_to_change(cifs_i, fattr->cf_eof)) {
200 i_size_write(inode, fattr->cf_eof);
Christoph Hellwig75f12982008-02-25 20:25:21 +0000201
202 /*
203 * i_blocks is not related to (i_size / i_blksize),
204 * but instead 512 byte (2**9) size is required for
205 * calculating num blocks.
206 */
Jeff Laytoncc0bad72009-06-25 00:56:52 -0400207 inode->i_blocks = (512 - 1 + fattr->cf_bytes) >> 9;
Christoph Hellwig75f12982008-02-25 20:25:21 +0000208 }
209 spin_unlock(&inode->i_lock);
Jeff Laytoncc0bad72009-06-25 00:56:52 -0400210
David Howells01c64fe2011-01-14 18:45:47 +0000211 if (fattr->cf_flags & CIFS_FATTR_DFS_REFERRAL)
212 inode->i_flags |= S_AUTOMOUNT;
Jeff Laytonc2b93e02013-05-07 11:28:31 -0400213 if (inode->i_state & I_NEW)
214 cifs_set_ops(inode);
Christoph Hellwig75f12982008-02-25 20:25:21 +0000215}
216
Jeff Layton4065c802010-05-17 07:18:58 -0400217void
218cifs_fill_uniqueid(struct super_block *sb, struct cifs_fattr *fattr)
219{
220 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
221
222 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)
223 return;
224
225 fattr->cf_uniqueid = iunique(sb, ROOT_I);
226}
227
Jeff Laytoncc0bad72009-06-25 00:56:52 -0400228/* Fill a cifs_fattr struct with info from FILE_UNIX_BASIC_INFO. */
229void
230cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, FILE_UNIX_BASIC_INFO *info,
231 struct cifs_sb_info *cifs_sb)
232{
233 memset(fattr, 0, sizeof(*fattr));
234 fattr->cf_uniqueid = le64_to_cpu(info->UniqueId);
235 fattr->cf_bytes = le64_to_cpu(info->NumOfBytes);
236 fattr->cf_eof = le64_to_cpu(info->EndOfFile);
237
238 fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime);
239 fattr->cf_mtime = cifs_NTtimeToUnix(info->LastModificationTime);
240 fattr->cf_ctime = cifs_NTtimeToUnix(info->LastStatusChange);
Steve French6e70e262017-09-21 21:32:29 -0500241 /* old POSIX extensions don't get create time */
242
Jeff Laytoncc0bad72009-06-25 00:56:52 -0400243 fattr->cf_mode = le64_to_cpu(info->Permissions);
244
245 /*
246 * Since we set the inode type below we need to mask off
247 * to avoid strange results if bits set above.
248 */
249 fattr->cf_mode &= ~S_IFMT;
250 switch (le32_to_cpu(info->Type)) {
251 case UNIX_FILE:
252 fattr->cf_mode |= S_IFREG;
253 fattr->cf_dtype = DT_REG;
254 break;
255 case UNIX_SYMLINK:
256 fattr->cf_mode |= S_IFLNK;
257 fattr->cf_dtype = DT_LNK;
258 break;
259 case UNIX_DIR:
260 fattr->cf_mode |= S_IFDIR;
261 fattr->cf_dtype = DT_DIR;
262 break;
263 case UNIX_CHARDEV:
264 fattr->cf_mode |= S_IFCHR;
265 fattr->cf_dtype = DT_CHR;
266 fattr->cf_rdev = MKDEV(le64_to_cpu(info->DevMajor),
267 le64_to_cpu(info->DevMinor) & MINORMASK);
268 break;
269 case UNIX_BLOCKDEV:
270 fattr->cf_mode |= S_IFBLK;
271 fattr->cf_dtype = DT_BLK;
272 fattr->cf_rdev = MKDEV(le64_to_cpu(info->DevMajor),
273 le64_to_cpu(info->DevMinor) & MINORMASK);
274 break;
275 case UNIX_FIFO:
276 fattr->cf_mode |= S_IFIFO;
277 fattr->cf_dtype = DT_FIFO;
278 break;
279 case UNIX_SOCKET:
280 fattr->cf_mode |= S_IFSOCK;
281 fattr->cf_dtype = DT_SOCK;
282 break;
283 default:
284 /* safest to call it a file if we do not know */
285 fattr->cf_mode |= S_IFREG;
286 fattr->cf_dtype = DT_REG;
Joe Perchesf96637b2013-05-04 22:12:25 -0500287 cifs_dbg(FYI, "unknown type %d\n", le32_to_cpu(info->Type));
Jeff Laytoncc0bad72009-06-25 00:56:52 -0400288 break;
289 }
290
Eric W. Biederman46bbc252013-02-05 23:55:44 -0800291 fattr->cf_uid = cifs_sb->mnt_uid;
292 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)) {
293 u64 id = le64_to_cpu(info->Uid);
Eric W. Biederman4a2c8cf2013-02-06 01:53:25 -0800294 if (id < ((uid_t)-1)) {
295 kuid_t uid = make_kuid(&init_user_ns, id);
296 if (uid_valid(uid))
297 fattr->cf_uid = uid;
298 }
Eric W. Biederman46bbc252013-02-05 23:55:44 -0800299 }
300
301 fattr->cf_gid = cifs_sb->mnt_gid;
302 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)) {
303 u64 id = le64_to_cpu(info->Gid);
Eric W. Biederman4a2c8cf2013-02-06 01:53:25 -0800304 if (id < ((gid_t)-1)) {
305 kgid_t gid = make_kgid(&init_user_ns, id);
306 if (gid_valid(gid))
307 fattr->cf_gid = gid;
308 }
Eric W. Biederman46bbc252013-02-05 23:55:44 -0800309 }
Jeff Laytoncc0bad72009-06-25 00:56:52 -0400310
311 fattr->cf_nlink = le64_to_cpu(info->Nlinks);
312}
Steve Frenchb9a3260f2008-05-20 21:52:32 +0000313
314/*
Jeff Laytoncc0bad72009-06-25 00:56:52 -0400315 * Fill a cifs_fattr struct with fake inode info.
316 *
317 * Needed to setup cifs_fattr data for the directory which is the
318 * junction to the new submount (ie to setup the fake directory
319 * which represents a DFS referral).
Steve Frenchb9a3260f2008-05-20 21:52:32 +0000320 */
Steve Frenchf1230c92009-07-22 23:13:01 +0000321static void
Jeff Laytoncc0bad72009-06-25 00:56:52 -0400322cifs_create_dfs_fattr(struct cifs_fattr *fattr, struct super_block *sb)
Steve French0e4bbde2008-05-20 19:50:46 +0000323{
Jeff Laytoncc0bad72009-06-25 00:56:52 -0400324 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
Steve French0e4bbde2008-05-20 19:50:46 +0000325
Joe Perchesf96637b2013-05-04 22:12:25 -0500326 cifs_dbg(FYI, "creating fake fattr for DFS referral\n");
Steve French0e4bbde2008-05-20 19:50:46 +0000327
Jeff Laytoncc0bad72009-06-25 00:56:52 -0400328 memset(fattr, 0, sizeof(*fattr));
329 fattr->cf_mode = S_IFDIR | S_IXUGO | S_IRWXU;
330 fattr->cf_uid = cifs_sb->mnt_uid;
331 fattr->cf_gid = cifs_sb->mnt_gid;
Arnd Bergmann95390202018-06-19 17:27:58 +0200332 ktime_get_real_ts64(&fattr->cf_mtime);
333 fattr->cf_mtime = timespec64_trunc(fattr->cf_mtime, sb->s_time_gran);
Deepa Dinamanie37fea52017-05-08 15:59:16 -0700334 fattr->cf_atime = fattr->cf_ctime = fattr->cf_mtime;
Jeff Laytoncc0bad72009-06-25 00:56:52 -0400335 fattr->cf_nlink = 2;
336 fattr->cf_flags |= CIFS_FATTR_DFS_REFERRAL;
Steve French0e4bbde2008-05-20 19:50:46 +0000337}
338
Pavel Shilovsky4ad65042012-09-18 16:20:26 -0700339static int
340cifs_get_file_info_unix(struct file *filp)
Jeff Laytonabab0952010-02-12 07:44:18 -0500341{
342 int rc;
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +0400343 unsigned int xid;
Jeff Laytonabab0952010-02-12 07:44:18 -0500344 FILE_UNIX_BASIC_INFO find_data;
345 struct cifs_fattr fattr;
Al Viro496ad9a2013-01-23 17:07:38 -0500346 struct inode *inode = file_inode(filp);
Jeff Laytonabab0952010-02-12 07:44:18 -0500347 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
Joe Perchesc21dfb62010-07-12 13:50:14 -0700348 struct cifsFileInfo *cfile = filp->private_data;
Steve French96daf2b2011-05-27 04:34:02 +0000349 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
Jeff Laytonabab0952010-02-12 07:44:18 -0500350
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +0400351 xid = get_xid();
Pavel Shilovsky4b4de762012-09-18 16:20:26 -0700352 rc = CIFSSMBUnixQFileInfo(xid, tcon, cfile->fid.netfid, &find_data);
Jeff Laytonabab0952010-02-12 07:44:18 -0500353 if (!rc) {
354 cifs_unix_basic_to_fattr(&fattr, &find_data, cifs_sb);
355 } else if (rc == -EREMOTE) {
356 cifs_create_dfs_fattr(&fattr, inode->i_sb);
357 rc = 0;
358 }
359
360 cifs_fattr_to_inode(inode, &fattr);
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +0400361 free_xid(xid);
Jeff Laytonabab0952010-02-12 07:44:18 -0500362 return rc;
363}
364
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365int cifs_get_inode_info_unix(struct inode **pinode,
Jeff Laytoncc0bad72009-06-25 00:56:52 -0400366 const unsigned char *full_path,
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +0400367 struct super_block *sb, unsigned int xid)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700368{
Jeff Laytoncc0bad72009-06-25 00:56:52 -0400369 int rc;
Steve French0e4bbde2008-05-20 19:50:46 +0000370 FILE_UNIX_BASIC_INFO find_data;
Jeff Laytoncc0bad72009-06-25 00:56:52 -0400371 struct cifs_fattr fattr;
Steve French96daf2b2011-05-27 04:34:02 +0000372 struct cifs_tcon *tcon;
Jeff Layton7ffec372010-09-29 19:51:11 -0400373 struct tcon_link *tlink;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700374 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375
Joe Perchesf96637b2013-05-04 22:12:25 -0500376 cifs_dbg(FYI, "Getting info on %s\n", full_path);
Igor Mammedov79626702008-03-09 03:44:18 +0000377
Jeff Layton7ffec372010-09-29 19:51:11 -0400378 tlink = cifs_sb_tlink(cifs_sb);
379 if (IS_ERR(tlink))
380 return PTR_ERR(tlink);
381 tcon = tlink_tcon(tlink);
382
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383 /* could have done a find first instead but this returns more info */
Jeff Laytoncc0bad72009-06-25 00:56:52 -0400384 rc = CIFSSMBUnixQPathInfo(xid, tcon, full_path, &find_data,
Nakajima Akirabc8ebdc42015-02-13 15:35:58 +0900385 cifs_sb->local_nls, cifs_remap(cifs_sb));
Jeff Layton7ffec372010-09-29 19:51:11 -0400386 cifs_put_tlink(tlink);
Jeff Laytoncc0bad72009-06-25 00:56:52 -0400387
388 if (!rc) {
389 cifs_unix_basic_to_fattr(&fattr, &find_data, cifs_sb);
390 } else if (rc == -EREMOTE) {
391 cifs_create_dfs_fattr(&fattr, sb);
Jeff Laytone911d0c2008-07-12 13:47:59 -0700392 rc = 0;
Jeff Laytoncc0bad72009-06-25 00:56:52 -0400393 } else {
394 return rc;
Steve French0e4bbde2008-05-20 19:50:46 +0000395 }
396
Stefan Metzmacher1b12b9c2010-08-05 21:19:56 +0200397 /* check for Minshall+French symlinks */
398 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) {
Sachin Prabhucb084b12013-11-25 17:09:50 +0000399 int tmprc = check_mf_symlink(xid, tcon, cifs_sb, &fattr,
400 full_path);
Stefan Metzmacher1b12b9c2010-08-05 21:19:56 +0200401 if (tmprc)
Sachin Prabhucb084b12013-11-25 17:09:50 +0000402 cifs_dbg(FYI, "check_mf_symlink: %d\n", tmprc);
Stefan Metzmacher1b12b9c2010-08-05 21:19:56 +0200403 }
404
Jeff Laytoncc0bad72009-06-25 00:56:52 -0400405 if (*pinode == NULL) {
406 /* get new inode */
Jeff Layton4065c802010-05-17 07:18:58 -0400407 cifs_fill_uniqueid(sb, &fattr);
Jeff Laytoncc0bad72009-06-25 00:56:52 -0400408 *pinode = cifs_iget(sb, &fattr);
409 if (!*pinode)
410 rc = -ENOMEM;
411 } else {
412 /* we already have inode, update it */
Nakajima Akira7196ac12015-04-22 15:24:44 +0900413
414 /* if uniqueid is different, return error */
415 if (unlikely(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM &&
416 CIFS_I(*pinode)->uniqueid != fattr.cf_uniqueid)) {
417 rc = -ESTALE;
418 goto cgiiu_exit;
419 }
420
421 /* if filetype is different, return error */
422 if (unlikely(((*pinode)->i_mode & S_IFMT) !=
423 (fattr.cf_mode & S_IFMT))) {
424 rc = -ESTALE;
425 goto cgiiu_exit;
426 }
427
Jeff Laytoncc0bad72009-06-25 00:56:52 -0400428 cifs_fattr_to_inode(*pinode, &fattr);
429 }
Steve French0e4bbde2008-05-20 19:50:46 +0000430
Nakajima Akira7196ac12015-04-22 15:24:44 +0900431cgiiu_exit:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432 return rc;
433}
434
Jeff Layton0b8f18e2009-07-09 01:46:37 -0400435static int
Pavel Shilovsky0360d602014-01-16 15:53:35 +0400436cifs_sfu_type(struct cifs_fattr *fattr, const char *path,
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +0400437 struct cifs_sb_info *cifs_sb, unsigned int xid)
Steve Frenchd6e2f2a42005-11-15 16:43:39 -0800438{
439 int rc;
Steve Frenchdb8b6312014-09-22 05:13:55 -0500440 __u32 oplock;
Jeff Layton7ffec372010-09-29 19:51:11 -0400441 struct tcon_link *tlink;
Steve French96daf2b2011-05-27 04:34:02 +0000442 struct cifs_tcon *tcon;
Pavel Shilovskyd81b8a42014-01-16 15:53:36 +0400443 struct cifs_fid fid;
444 struct cifs_open_parms oparms;
Pavel Shilovskyd4ffff12011-05-26 06:02:00 +0000445 struct cifs_io_parms io_parms;
Steve French86c96b42005-11-18 20:25:31 -0800446 char buf[24];
Steve Frenchd6e2f2a42005-11-15 16:43:39 -0800447 unsigned int bytes_read;
Steve Frenchfb8c4b12007-07-10 01:16:18 +0000448 char *pbuf;
Pavel Shilovsky0360d602014-01-16 15:53:35 +0400449 int buf_type = CIFS_NO_BUFFER;
Steve Frenchd6e2f2a42005-11-15 16:43:39 -0800450
451 pbuf = buf;
452
Jeff Layton0b8f18e2009-07-09 01:46:37 -0400453 fattr->cf_mode &= ~S_IFMT;
454
455 if (fattr->cf_eof == 0) {
456 fattr->cf_mode |= S_IFIFO;
457 fattr->cf_dtype = DT_FIFO;
Steve Frenchd6e2f2a42005-11-15 16:43:39 -0800458 return 0;
Jeff Layton0b8f18e2009-07-09 01:46:37 -0400459 } else if (fattr->cf_eof < 8) {
460 fattr->cf_mode |= S_IFREG;
461 fattr->cf_dtype = DT_REG;
Steve Frenchd6e2f2a42005-11-15 16:43:39 -0800462 return -EINVAL; /* EOPNOTSUPP? */
463 }
Steve French50c2f752007-07-13 00:33:32 +0000464
Jeff Layton7ffec372010-09-29 19:51:11 -0400465 tlink = cifs_sb_tlink(cifs_sb);
466 if (IS_ERR(tlink))
467 return PTR_ERR(tlink);
468 tcon = tlink_tcon(tlink);
469
Pavel Shilovskyd81b8a42014-01-16 15:53:36 +0400470 oparms.tcon = tcon;
471 oparms.cifs_sb = cifs_sb;
472 oparms.desired_access = GENERIC_READ;
473 oparms.create_options = CREATE_NOT_DIR;
Steve French5e196972018-08-27 17:04:13 -0500474 if (backup_cred(cifs_sb))
475 oparms.create_options |= CREATE_OPEN_BACKUP_INTENT;
Pavel Shilovskyd81b8a42014-01-16 15:53:36 +0400476 oparms.disposition = FILE_OPEN;
477 oparms.path = path;
478 oparms.fid = &fid;
479 oparms.reconnect = false;
480
Steve Frenchdb8b6312014-09-22 05:13:55 -0500481 if (tcon->ses->server->oplocks)
482 oplock = REQ_OPLOCK;
483 else
484 oplock = 0;
485 rc = tcon->ses->server->ops->open(xid, &oparms, &oplock, NULL);
Pavel Shilovsky0360d602014-01-16 15:53:35 +0400486 if (rc) {
Steve Frenchdb8b6312014-09-22 05:13:55 -0500487 cifs_dbg(FYI, "check sfu type of %s, open rc = %d\n", path, rc);
Pavel Shilovsky0360d602014-01-16 15:53:35 +0400488 cifs_put_tlink(tlink);
489 return rc;
Steve Frenchd6e2f2a42005-11-15 16:43:39 -0800490 }
Pavel Shilovsky0360d602014-01-16 15:53:35 +0400491
492 /* Read header */
Pavel Shilovskyd81b8a42014-01-16 15:53:36 +0400493 io_parms.netfid = fid.netfid;
Pavel Shilovsky0360d602014-01-16 15:53:35 +0400494 io_parms.pid = current->tgid;
495 io_parms.tcon = tcon;
496 io_parms.offset = 0;
497 io_parms.length = 24;
498
Steve Frenchdb8b6312014-09-22 05:13:55 -0500499 rc = tcon->ses->server->ops->sync_read(xid, &fid, &io_parms,
500 &bytes_read, &pbuf, &buf_type);
Pavel Shilovsky0360d602014-01-16 15:53:35 +0400501 if ((rc == 0) && (bytes_read >= 8)) {
502 if (memcmp("IntxBLK", pbuf, 8) == 0) {
503 cifs_dbg(FYI, "Block device\n");
504 fattr->cf_mode |= S_IFBLK;
505 fattr->cf_dtype = DT_BLK;
506 if (bytes_read == 24) {
507 /* we have enough to decode dev num */
508 __u64 mjr; /* major */
509 __u64 mnr; /* minor */
510 mjr = le64_to_cpu(*(__le64 *)(pbuf+8));
511 mnr = le64_to_cpu(*(__le64 *)(pbuf+16));
512 fattr->cf_rdev = MKDEV(mjr, mnr);
513 }
514 } else if (memcmp("IntxCHR", pbuf, 8) == 0) {
515 cifs_dbg(FYI, "Char device\n");
516 fattr->cf_mode |= S_IFCHR;
517 fattr->cf_dtype = DT_CHR;
518 if (bytes_read == 24) {
519 /* we have enough to decode dev num */
520 __u64 mjr; /* major */
521 __u64 mnr; /* minor */
522 mjr = le64_to_cpu(*(__le64 *)(pbuf+8));
523 mnr = le64_to_cpu(*(__le64 *)(pbuf+16));
524 fattr->cf_rdev = MKDEV(mjr, mnr);
525 }
526 } else if (memcmp("IntxLNK", pbuf, 7) == 0) {
527 cifs_dbg(FYI, "Symlink\n");
528 fattr->cf_mode |= S_IFLNK;
529 fattr->cf_dtype = DT_LNK;
530 } else {
531 fattr->cf_mode |= S_IFREG; /* file? */
532 fattr->cf_dtype = DT_REG;
533 rc = -EOPNOTSUPP;
534 }
535 } else {
536 fattr->cf_mode |= S_IFREG; /* then it is a file */
537 fattr->cf_dtype = DT_REG;
538 rc = -EOPNOTSUPP; /* or some unknown SFU type */
539 }
Steve Frenchdb8b6312014-09-22 05:13:55 -0500540
541 tcon->ses->server->ops->close(xid, tcon, &fid);
Jeff Layton7ffec372010-09-29 19:51:11 -0400542 cifs_put_tlink(tlink);
Steve Frenchd6e2f2a42005-11-15 16:43:39 -0800543 return rc;
Steve Frenchd6e2f2a42005-11-15 16:43:39 -0800544}
545
Steve French9e294f12005-11-17 16:59:21 -0800546#define SFBITS_MASK (S_ISVTX | S_ISGID | S_ISUID) /* SETFILEBITS valid bits */
547
Jeff Layton0b8f18e2009-07-09 01:46:37 -0400548/*
549 * Fetch mode bits as provided by SFU.
550 *
551 * FIXME: Doesn't this clobber the type bit we got from cifs_sfu_type ?
552 */
553static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path,
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +0400554 struct cifs_sb_info *cifs_sb, unsigned int xid)
Steve French9e294f12005-11-17 16:59:21 -0800555{
Steve French3020a1f2005-11-18 11:31:10 -0800556#ifdef CONFIG_CIFS_XATTR
Steve French9e294f12005-11-17 16:59:21 -0800557 ssize_t rc;
558 char ea_value[4];
559 __u32 mode;
Jeff Layton7ffec372010-09-29 19:51:11 -0400560 struct tcon_link *tlink;
Steve French96daf2b2011-05-27 04:34:02 +0000561 struct cifs_tcon *tcon;
Steve French9e294f12005-11-17 16:59:21 -0800562
Jeff Layton7ffec372010-09-29 19:51:11 -0400563 tlink = cifs_sb_tlink(cifs_sb);
564 if (IS_ERR(tlink))
565 return PTR_ERR(tlink);
566 tcon = tlink_tcon(tlink);
567
Steve Frenchd979f3b2014-02-01 23:27:18 -0600568 if (tcon->ses->server->ops->query_all_EAs == NULL) {
569 cifs_put_tlink(tlink);
570 return -EOPNOTSUPP;
571 }
572
573 rc = tcon->ses->server->ops->query_all_EAs(xid, tcon, path,
574 "SETFILEBITS", ea_value, 4 /* size of buf */,
Steve French67b4c882017-05-12 20:59:10 -0500575 cifs_sb);
Jeff Layton7ffec372010-09-29 19:51:11 -0400576 cifs_put_tlink(tlink);
Steve French4523cc32007-04-30 20:13:06 +0000577 if (rc < 0)
Steve French9e294f12005-11-17 16:59:21 -0800578 return (int)rc;
579 else if (rc > 3) {
580 mode = le32_to_cpu(*((__le32 *)ea_value));
Jeff Layton0b8f18e2009-07-09 01:46:37 -0400581 fattr->cf_mode &= ~SFBITS_MASK;
Joe Perchesf96637b2013-05-04 22:12:25 -0500582 cifs_dbg(FYI, "special bits 0%o org mode 0%o\n",
583 mode, fattr->cf_mode);
Jeff Layton0b8f18e2009-07-09 01:46:37 -0400584 fattr->cf_mode = (mode & SFBITS_MASK) | fattr->cf_mode;
Joe Perchesf96637b2013-05-04 22:12:25 -0500585 cifs_dbg(FYI, "special mode bits 0%o\n", mode);
Steve French9e294f12005-11-17 16:59:21 -0800586 }
Jeff Layton0b8f18e2009-07-09 01:46:37 -0400587
588 return 0;
Steve French3020a1f2005-11-18 11:31:10 -0800589#else
590 return -EOPNOTSUPP;
591#endif
Steve French9e294f12005-11-17 16:59:21 -0800592}
593
Jeff Layton0b8f18e2009-07-09 01:46:37 -0400594/* Fill a cifs_fattr struct with info from FILE_ALL_INFO */
Steve Frenchf1230c92009-07-22 23:13:01 +0000595static void
Jeff Layton0b8f18e2009-07-09 01:46:37 -0400596cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
Deepa Dinamanie37fea52017-05-08 15:59:16 -0700597 struct super_block *sb, bool adjust_tz,
Pavel Shilovskyeb85d94b2013-10-23 17:49:47 +0400598 bool symlink)
Steve Frenchb9a3260f2008-05-20 21:52:32 +0000599{
Deepa Dinamanie37fea52017-05-08 15:59:16 -0700600 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
Steve French96daf2b2011-05-27 04:34:02 +0000601 struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
Jeff Layton0d424ad2010-09-20 16:01:35 -0700602
Jeff Layton0b8f18e2009-07-09 01:46:37 -0400603 memset(fattr, 0, sizeof(*fattr));
604 fattr->cf_cifsattrs = le32_to_cpu(info->Attributes);
605 if (info->DeletePending)
606 fattr->cf_flags |= CIFS_FATTR_DELETE_PENDING;
Steve Frenchb9a3260f2008-05-20 21:52:32 +0000607
Jeff Layton0b8f18e2009-07-09 01:46:37 -0400608 if (info->LastAccessTime)
609 fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime);
Deepa Dinamanie37fea52017-05-08 15:59:16 -0700610 else {
Arnd Bergmann95390202018-06-19 17:27:58 +0200611 ktime_get_real_ts64(&fattr->cf_atime);
612 fattr->cf_atime = timespec64_trunc(fattr->cf_atime, sb->s_time_gran);
Deepa Dinamanie37fea52017-05-08 15:59:16 -0700613 }
Jeff Layton0b8f18e2009-07-09 01:46:37 -0400614
615 fattr->cf_ctime = cifs_NTtimeToUnix(info->ChangeTime);
616 fattr->cf_mtime = cifs_NTtimeToUnix(info->LastWriteTime);
617
618 if (adjust_tz) {
Jeff Layton0d424ad2010-09-20 16:01:35 -0700619 fattr->cf_ctime.tv_sec += tcon->ses->server->timeAdj;
620 fattr->cf_mtime.tv_sec += tcon->ses->server->timeAdj;
Jeff Layton0b8f18e2009-07-09 01:46:37 -0400621 }
622
623 fattr->cf_eof = le64_to_cpu(info->EndOfFile);
624 fattr->cf_bytes = le64_to_cpu(info->AllocationSize);
Jeff Layton20054bd2011-01-07 11:30:27 -0500625 fattr->cf_createtime = le64_to_cpu(info->CreationTime);
Jeff Layton0b8f18e2009-07-09 01:46:37 -0400626
Jim McDonough74d290d2013-09-21 10:36:10 -0500627 fattr->cf_nlink = le32_to_cpu(info->NumberOfLinks);
Pavel Shilovskyeb85d94b2013-10-23 17:49:47 +0400628
629 if (symlink) {
630 fattr->cf_mode = S_IFLNK;
631 fattr->cf_dtype = DT_LNK;
632 } else if (fattr->cf_cifsattrs & ATTR_DIRECTORY) {
Jeff Layton0b8f18e2009-07-09 01:46:37 -0400633 fattr->cf_mode = S_IFDIR | cifs_sb->mnt_dir_mode;
634 fattr->cf_dtype = DT_DIR;
Pavel Shilovsky6de2ce42012-02-17 16:13:30 +0300635 /*
636 * Server can return wrong NumberOfLinks value for directories
637 * when Unix extensions are disabled - fake it.
638 */
Jim McDonough74d290d2013-09-21 10:36:10 -0500639 if (!tcon->unix_ext)
640 fattr->cf_flags |= CIFS_FATTR_UNKNOWN_NLINK;
Jeff Layton0b8f18e2009-07-09 01:46:37 -0400641 } else {
642 fattr->cf_mode = S_IFREG | cifs_sb->mnt_file_mode;
643 fattr->cf_dtype = DT_REG;
Jeff Layton0b8f18e2009-07-09 01:46:37 -0400644
Jeff Laytond0c280d2009-07-09 01:46:44 -0400645 /* clear write bits if ATTR_READONLY is set */
646 if (fattr->cf_cifsattrs & ATTR_READONLY)
647 fattr->cf_mode &= ~(S_IWUGO);
Jeff Layton0b8f18e2009-07-09 01:46:37 -0400648
Jim McDonough74d290d2013-09-21 10:36:10 -0500649 /*
650 * Don't accept zero nlink from non-unix servers unless
651 * delete is pending. Instead mark it as unknown.
652 */
653 if ((fattr->cf_nlink < 1) && !tcon->unix_ext &&
654 !info->DeletePending) {
655 cifs_dbg(1, "bogus file nlink value %u\n",
Steve French6658b9f2013-07-04 14:38:48 -0500656 fattr->cf_nlink);
Jim McDonough74d290d2013-09-21 10:36:10 -0500657 fattr->cf_flags |= CIFS_FATTR_UNKNOWN_NLINK;
Steve French6658b9f2013-07-04 14:38:48 -0500658 }
Pavel Shilovsky6de2ce42012-02-17 16:13:30 +0300659 }
Jeff Layton0b8f18e2009-07-09 01:46:37 -0400660
661 fattr->cf_uid = cifs_sb->mnt_uid;
662 fattr->cf_gid = cifs_sb->mnt_gid;
Steve Frenchb9a3260f2008-05-20 21:52:32 +0000663}
664
Pavel Shilovsky4ad65042012-09-18 16:20:26 -0700665static int
666cifs_get_file_info(struct file *filp)
Jeff Laytonabab0952010-02-12 07:44:18 -0500667{
668 int rc;
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +0400669 unsigned int xid;
Jeff Laytonabab0952010-02-12 07:44:18 -0500670 FILE_ALL_INFO find_data;
671 struct cifs_fattr fattr;
Al Viro496ad9a2013-01-23 17:07:38 -0500672 struct inode *inode = file_inode(filp);
Joe Perchesc21dfb62010-07-12 13:50:14 -0700673 struct cifsFileInfo *cfile = filp->private_data;
Steve French96daf2b2011-05-27 04:34:02 +0000674 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
Pavel Shilovsky4ad65042012-09-18 16:20:26 -0700675 struct TCP_Server_Info *server = tcon->ses->server;
676
677 if (!server->ops->query_file_info)
678 return -ENOSYS;
Jeff Laytonabab0952010-02-12 07:44:18 -0500679
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +0400680 xid = get_xid();
Pavel Shilovsky4ad65042012-09-18 16:20:26 -0700681 rc = server->ops->query_file_info(xid, tcon, &cfile->fid, &find_data);
Pavel Shilovsky42274bb2011-10-22 14:37:50 +0400682 switch (rc) {
683 case 0:
Deepa Dinamanie37fea52017-05-08 15:59:16 -0700684 cifs_all_info_to_fattr(&fattr, &find_data, inode->i_sb, false,
Pavel Shilovskyeb85d94b2013-10-23 17:49:47 +0400685 false);
Pavel Shilovsky42274bb2011-10-22 14:37:50 +0400686 break;
687 case -EREMOTE:
688 cifs_create_dfs_fattr(&fattr, inode->i_sb);
689 rc = 0;
690 break;
691 case -EOPNOTSUPP:
692 case -EINVAL:
Jeff Laytonabab0952010-02-12 07:44:18 -0500693 /*
694 * FIXME: legacy server -- fall back to path-based call?
Steve Frenchff2157132010-03-09 20:30:42 +0000695 * for now, just skip revalidating and mark inode for
696 * immediate reval.
697 */
Jeff Laytonabab0952010-02-12 07:44:18 -0500698 rc = 0;
699 CIFS_I(inode)->time = 0;
Pavel Shilovsky42274bb2011-10-22 14:37:50 +0400700 default:
Jeff Laytonabab0952010-02-12 07:44:18 -0500701 goto cgfi_exit;
Pavel Shilovsky42274bb2011-10-22 14:37:50 +0400702 }
Jeff Laytonabab0952010-02-12 07:44:18 -0500703
704 /*
705 * don't bother with SFU junk here -- just mark inode as needing
706 * revalidation.
707 */
Jeff Laytonabab0952010-02-12 07:44:18 -0500708 fattr.cf_uniqueid = CIFS_I(inode)->uniqueid;
709 fattr.cf_flags |= CIFS_FATTR_NEED_REVAL;
710 cifs_fattr_to_inode(inode, &fattr);
711cgfi_exit:
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +0400712 free_xid(xid);
Jeff Laytonabab0952010-02-12 07:44:18 -0500713 return rc;
714}
715
Steve French7ea884c2018-03-31 18:13:38 -0500716/* Simple function to return a 64 bit hash of string. Rarely called */
717static __u64 simple_hashstr(const char *str)
718{
Geert Uytterhoeven3995bbf2018-04-05 14:57:11 +0200719 const __u64 hash_mult = 1125899906842597ULL; /* a big enough prime */
Steve French7ea884c2018-03-31 18:13:38 -0500720 __u64 hash = 0;
721
722 while (*str)
723 hash = (hash + (__u64) *str++) * hash_mult;
724
725 return hash;
726}
727
Pavel Shilovsky1208ef12012-05-27 17:34:43 +0400728int
729cifs_get_inode_info(struct inode **inode, const char *full_path,
730 FILE_ALL_INFO *data, struct super_block *sb, int xid,
Steve French42eacf92014-02-10 14:08:16 -0600731 const struct cifs_fid *fid)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700732{
Shirish Pargaonkarc052e2b2012-09-28 12:21:14 -0500733 bool validinum = false;
734 __u16 srchflgs;
735 int rc = 0, tmprc = ENOSYS;
Pavel Shilovsky1208ef12012-05-27 17:34:43 +0400736 struct cifs_tcon *tcon;
737 struct TCP_Server_Info *server;
Jeff Layton7ffec372010-09-29 19:51:11 -0400738 struct tcon_link *tlink;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700739 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700740 char *buf = NULL;
Pavel Shilovsky1208ef12012-05-27 17:34:43 +0400741 bool adjust_tz = false;
Jeff Layton0b8f18e2009-07-09 01:46:37 -0400742 struct cifs_fattr fattr;
Shirish Pargaonkarc052e2b2012-09-28 12:21:14 -0500743 struct cifs_search_info *srchinf = NULL;
Pavel Shilovskyeb85d94b2013-10-23 17:49:47 +0400744 bool symlink = false;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700745
Jeff Layton7ffec372010-09-29 19:51:11 -0400746 tlink = cifs_sb_tlink(cifs_sb);
747 if (IS_ERR(tlink))
748 return PTR_ERR(tlink);
Pavel Shilovsky1208ef12012-05-27 17:34:43 +0400749 tcon = tlink_tcon(tlink);
750 server = tcon->ses->server;
Jeff Layton7ffec372010-09-29 19:51:11 -0400751
Joe Perchesf96637b2013-05-04 22:12:25 -0500752 cifs_dbg(FYI, "Getting info on %s\n", full_path);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700753
Pavel Shilovsky1208ef12012-05-27 17:34:43 +0400754 if ((data == NULL) && (*inode != NULL)) {
Ronnie Sahlberg57c55cd2018-05-24 06:54:27 +1000755 if (CIFS_CACHE_READ(CIFS_I(*inode)) &&
756 CIFS_I(*inode)->time != 0) {
Joe Perchesf96637b2013-05-04 22:12:25 -0500757 cifs_dbg(FYI, "No need to revalidate cached inode sizes\n");
Jeff Layton7ffec372010-09-29 19:51:11 -0400758 goto cgii_exit;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700759 }
760 }
761
Pavel Shilovsky1208ef12012-05-27 17:34:43 +0400762 /* if inode info is not passed, get it from server */
763 if (data == NULL) {
764 if (!server->ops->query_path_info) {
765 rc = -ENOSYS;
766 goto cgii_exit;
767 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700768 buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
Jeff Layton7ffec372010-09-29 19:51:11 -0400769 if (buf == NULL) {
770 rc = -ENOMEM;
771 goto cgii_exit;
772 }
Pavel Shilovsky1208ef12012-05-27 17:34:43 +0400773 data = (FILE_ALL_INFO *)buf;
774 rc = server->ops->query_path_info(xid, tcon, cifs_sb, full_path,
Pavel Shilovskyeb85d94b2013-10-23 17:49:47 +0400775 data, &adjust_tz, &symlink);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700776 }
Jeff Layton0b8f18e2009-07-09 01:46:37 -0400777
778 if (!rc) {
Deepa Dinamanie37fea52017-05-08 15:59:16 -0700779 cifs_all_info_to_fattr(&fattr, data, sb, adjust_tz,
Pavel Shilovskyeb85d94b2013-10-23 17:49:47 +0400780 symlink);
Jeff Layton0b8f18e2009-07-09 01:46:37 -0400781 } else if (rc == -EREMOTE) {
782 cifs_create_dfs_fattr(&fattr, sb);
Steve Frenchb9a3260f2008-05-20 21:52:32 +0000783 rc = 0;
Steve French1e77a8c2018-10-19 00:45:21 -0500784 } else if ((rc == -EACCES) && backup_cred(cifs_sb) &&
785 (strcmp(server->vals->version_string, SMB1_VERSION_STRING)
786 == 0)) {
Steve French3b7960c2018-10-19 01:58:22 -0500787 /*
788 * For SMB2 and later the backup intent flag is already
789 * sent if needed on open and there is no path based
790 * FindFirst operation to use to retry with
791 */
Steve French1e77a8c2018-10-19 00:45:21 -0500792
Steve French3b7960c2018-10-19 01:58:22 -0500793 srchinf = kzalloc(sizeof(struct cifs_search_info),
794 GFP_KERNEL);
795 if (srchinf == NULL) {
796 rc = -ENOMEM;
797 goto cgii_exit;
798 }
Shirish Pargaonkarc052e2b2012-09-28 12:21:14 -0500799
Steve French3b7960c2018-10-19 01:58:22 -0500800 srchinf->endOfSearch = false;
801 if (tcon->unix_ext)
802 srchinf->info_level = SMB_FIND_FILE_UNIX;
803 else if ((tcon->ses->capabilities &
804 tcon->ses->server->vals->cap_nt_find) == 0)
805 srchinf->info_level = SMB_FIND_FILE_INFO_STANDARD;
806 else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)
Shirish Pargaonkarc052e2b2012-09-28 12:21:14 -0500807 srchinf->info_level = SMB_FIND_FILE_ID_FULL_DIR_INFO;
Steve French3b7960c2018-10-19 01:58:22 -0500808 else /* no srvino useful for fallback to some netapp */
809 srchinf->info_level = SMB_FIND_FILE_DIRECTORY_INFO;
Shirish Pargaonkarc052e2b2012-09-28 12:21:14 -0500810
Steve French3b7960c2018-10-19 01:58:22 -0500811 srchflgs = CIFS_SEARCH_CLOSE_ALWAYS |
812 CIFS_SEARCH_CLOSE_AT_END |
813 CIFS_SEARCH_BACKUP_SEARCH;
Shirish Pargaonkarc052e2b2012-09-28 12:21:14 -0500814
Steve French3b7960c2018-10-19 01:58:22 -0500815 rc = CIFSFindFirst(xid, tcon, full_path,
816 cifs_sb, NULL, srchflgs, srchinf, false);
817 if (!rc) {
818 data = (FILE_ALL_INFO *)srchinf->srch_entries_start;
Shirish Pargaonkarc052e2b2012-09-28 12:21:14 -0500819
Steve French3b7960c2018-10-19 01:58:22 -0500820 cifs_dir_info_to_fattr(&fattr,
821 (FILE_DIRECTORY_INFO *)data, cifs_sb);
822 fattr.cf_uniqueid = le64_to_cpu(
823 ((SEARCH_ID_FULL_DIR_INFO *)data)->UniqueId);
824 validinum = true;
Shirish Pargaonkarc052e2b2012-09-28 12:21:14 -0500825
Steve French3b7960c2018-10-19 01:58:22 -0500826 cifs_buf_release(srchinf->ntwrk_buf_start);
827 }
828 kfree(srchinf);
829 if (rc)
830 goto cgii_exit;
Shirish Pargaonkarc052e2b2012-09-28 12:21:14 -0500831 } else
Igor Mammedov79626702008-03-09 03:44:18 +0000832 goto cgii_exit;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700833
Jeff Layton0b8f18e2009-07-09 01:46:37 -0400834 /*
835 * If an inode wasn't passed in, then get the inode number
836 *
837 * Is an i_ino of zero legal? Can we use that to check if the server
838 * supports returning inode numbers? Are there other sanity checks we
839 * can use to ensure that the server is really filling in that field?
Jeff Layton0b8f18e2009-07-09 01:46:37 -0400840 */
Pavel Shilovsky1208ef12012-05-27 17:34:43 +0400841 if (*inode == NULL) {
Steve Frenchb9a3260f2008-05-20 21:52:32 +0000842 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
Shirish Pargaonkarc052e2b2012-09-28 12:21:14 -0500843 if (validinum == false) {
844 if (server->ops->get_srv_inum)
845 tmprc = server->ops->get_srv_inum(xid,
846 tcon, cifs_sb, full_path,
847 &fattr.cf_uniqueid, data);
848 if (tmprc) {
Joe Perchesf96637b2013-05-04 22:12:25 -0500849 cifs_dbg(FYI, "GetSrvInodeNum rc %d\n",
850 tmprc);
Shirish Pargaonkarc052e2b2012-09-28 12:21:14 -0500851 fattr.cf_uniqueid = iunique(sb, ROOT_I);
852 cifs_autodisable_serverino(cifs_sb);
Steve French7ea884c2018-03-31 18:13:38 -0500853 } else if ((fattr.cf_uniqueid == 0) &&
854 strlen(full_path) == 0) {
855 /* some servers ret bad root ino ie 0 */
856 cifs_dbg(FYI, "Invalid (0) inodenum\n");
857 fattr.cf_flags |=
858 CIFS_FATTR_FAKE_ROOT_INO;
859 fattr.cf_uniqueid =
860 simple_hashstr(tcon->treeName);
Shirish Pargaonkarc052e2b2012-09-28 12:21:14 -0500861 }
Jeff Layton132ac7b2009-02-10 07:33:57 -0500862 }
Shirish Pargaonkarc052e2b2012-09-28 12:21:14 -0500863 } else
Jeff Layton0b8f18e2009-07-09 01:46:37 -0400864 fattr.cf_uniqueid = iunique(sb, ROOT_I);
Ross Lagerwalla108471b2015-12-02 14:46:08 +0000865 } else {
866 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) &&
867 validinum == false && server->ops->get_srv_inum) {
868 /*
869 * Pass a NULL tcon to ensure we don't make a round
870 * trip to the server. This only works for SMB2+.
871 */
872 tmprc = server->ops->get_srv_inum(xid,
873 NULL, cifs_sb, full_path,
874 &fattr.cf_uniqueid, data);
875 if (tmprc)
876 fattr.cf_uniqueid = CIFS_I(*inode)->uniqueid;
Steve French7ea884c2018-03-31 18:13:38 -0500877 else if ((fattr.cf_uniqueid == 0) &&
878 strlen(full_path) == 0) {
879 /*
880 * Reuse existing root inode num since
881 * inum zero for root causes ls of . and .. to
882 * not be returned
883 */
884 cifs_dbg(FYI, "Srv ret 0 inode num for root\n");
885 fattr.cf_uniqueid = CIFS_I(*inode)->uniqueid;
886 }
Ross Lagerwalla108471b2015-12-02 14:46:08 +0000887 } else
888 fattr.cf_uniqueid = CIFS_I(*inode)->uniqueid;
889 }
Steve Frenchb9a3260f2008-05-20 21:52:32 +0000890
Jeff Layton0b8f18e2009-07-09 01:46:37 -0400891 /* query for SFU type info if supported and needed */
892 if (fattr.cf_cifsattrs & ATTR_SYSTEM &&
893 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
894 tmprc = cifs_sfu_type(&fattr, full_path, cifs_sb, xid);
895 if (tmprc)
Joe Perchesf96637b2013-05-04 22:12:25 -0500896 cifs_dbg(FYI, "cifs_sfu_type failed: %d\n", tmprc);
Steve Frenchb9a3260f2008-05-20 21:52:32 +0000897 }
Steve Frenchb9a3260f2008-05-20 21:52:32 +0000898
Jeff Layton79df1ba2010-12-06 12:52:08 -0500899#ifdef CONFIG_CIFS_ACL
Steve Frenchb9a3260f2008-05-20 21:52:32 +0000900 /* fill in 0777 bits from ACL */
901 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
Pavel Shilovsky1208ef12012-05-27 17:34:43 +0400902 rc = cifs_acl_to_fattr(cifs_sb, &fattr, *inode, full_path, fid);
Shirish Pargaonkar78415d22010-11-27 11:37:26 -0600903 if (rc) {
Joe Perchesf96637b2013-05-04 22:12:25 -0500904 cifs_dbg(FYI, "%s: Getting ACL failed with error: %d\n",
905 __func__, rc);
Shirish Pargaonkar78415d22010-11-27 11:37:26 -0600906 goto cgii_exit;
907 }
Steve Frenchb9a3260f2008-05-20 21:52:32 +0000908 }
Jeff Layton79df1ba2010-12-06 12:52:08 -0500909#endif /* CONFIG_CIFS_ACL */
Jeff Layton0b8f18e2009-07-09 01:46:37 -0400910
911 /* fill in remaining high mode bits e.g. SUID, VTX */
912 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)
913 cifs_sfu_mode(&fattr, full_path, cifs_sb, xid);
914
Stefan Metzmacher1b12b9c2010-08-05 21:19:56 +0200915 /* check for Minshall+French symlinks */
916 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) {
Sachin Prabhucb084b12013-11-25 17:09:50 +0000917 tmprc = check_mf_symlink(xid, tcon, cifs_sb, &fattr,
918 full_path);
Stefan Metzmacher1b12b9c2010-08-05 21:19:56 +0200919 if (tmprc)
Sachin Prabhucb084b12013-11-25 17:09:50 +0000920 cifs_dbg(FYI, "check_mf_symlink: %d\n", tmprc);
Stefan Metzmacher1b12b9c2010-08-05 21:19:56 +0200921 }
922
Pavel Shilovsky1208ef12012-05-27 17:34:43 +0400923 if (!*inode) {
924 *inode = cifs_iget(sb, &fattr);
925 if (!*inode)
Jeff Layton0b8f18e2009-07-09 01:46:37 -0400926 rc = -ENOMEM;
927 } else {
Nakajima Akira7196ac12015-04-22 15:24:44 +0900928 /* we already have inode, update it */
929
Ross Lagerwalla108471b2015-12-02 14:46:08 +0000930 /* if uniqueid is different, return error */
931 if (unlikely(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM &&
932 CIFS_I(*inode)->uniqueid != fattr.cf_uniqueid)) {
933 rc = -ESTALE;
934 goto cgii_exit;
935 }
936
Nakajima Akira7196ac12015-04-22 15:24:44 +0900937 /* if filetype is different, return error */
938 if (unlikely(((*inode)->i_mode & S_IFMT) !=
939 (fattr.cf_mode & S_IFMT))) {
940 rc = -ESTALE;
941 goto cgii_exit;
942 }
943
Pavel Shilovsky1208ef12012-05-27 17:34:43 +0400944 cifs_fattr_to_inode(*inode, &fattr);
Steve Frenchb9a3260f2008-05-20 21:52:32 +0000945 }
946
Igor Mammedov79626702008-03-09 03:44:18 +0000947cgii_exit:
Steve French7ea884c2018-03-31 18:13:38 -0500948 if ((*inode) && ((*inode)->i_ino == 0))
949 cifs_dbg(FYI, "inode number of zero returned\n");
950
Linus Torvalds1da177e2005-04-16 15:20:36 -0700951 kfree(buf);
Jeff Layton7ffec372010-09-29 19:51:11 -0400952 cifs_put_tlink(tlink);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700953 return rc;
954}
955
Steve French7f8ed422007-09-28 22:28:55 +0000956static const struct inode_operations cifs_ipc_inode_ops = {
957 .lookup = cifs_lookup,
958};
959
Jeff Laytoncc0bad72009-06-25 00:56:52 -0400960static int
961cifs_find_inode(struct inode *inode, void *opaque)
962{
963 struct cifs_fattr *fattr = (struct cifs_fattr *) opaque;
964
Jeff Laytonf30b9c12010-07-19 18:00:17 -0400965 /* don't match inode with different uniqueid */
Jeff Laytoncc0bad72009-06-25 00:56:52 -0400966 if (CIFS_I(inode)->uniqueid != fattr->cf_uniqueid)
967 return 0;
968
Jeff Layton20054bd2011-01-07 11:30:27 -0500969 /* use createtime like an i_generation field */
970 if (CIFS_I(inode)->createtime != fattr->cf_createtime)
971 return 0;
972
Jeff Laytonf30b9c12010-07-19 18:00:17 -0400973 /* don't match inode of different type */
974 if ((inode->i_mode & S_IFMT) != (fattr->cf_mode & S_IFMT))
975 return 0;
976
Jeff Layton5acfec22010-08-02 17:43:54 -0400977 /* if it's not a directory or has no dentries, then flag it */
Al Virob3d9b7a2012-06-09 13:51:19 -0400978 if (S_ISDIR(inode->i_mode) && !hlist_empty(&inode->i_dentry))
Jeff Layton3d694382010-05-11 14:59:55 -0400979 fattr->cf_flags |= CIFS_FATTR_INO_COLLISION;
Jeff Layton3d694382010-05-11 14:59:55 -0400980
Jeff Laytoncc0bad72009-06-25 00:56:52 -0400981 return 1;
982}
983
984static int
985cifs_init_inode(struct inode *inode, void *opaque)
986{
987 struct cifs_fattr *fattr = (struct cifs_fattr *) opaque;
988
989 CIFS_I(inode)->uniqueid = fattr->cf_uniqueid;
Jeff Layton20054bd2011-01-07 11:30:27 -0500990 CIFS_I(inode)->createtime = fattr->cf_createtime;
Jeff Laytoncc0bad72009-06-25 00:56:52 -0400991 return 0;
992}
993
Jeff Layton5acfec22010-08-02 17:43:54 -0400994/*
995 * walk dentry list for an inode and report whether it has aliases that
996 * are hashed. We use this to determine if a directory inode can actually
997 * be used.
998 */
999static bool
1000inode_has_hashed_dentries(struct inode *inode)
1001{
1002 struct dentry *dentry;
1003
Nick Piggin873feea2011-01-07 17:50:06 +11001004 spin_lock(&inode->i_lock);
Al Viro946e51f2014-10-26 19:19:16 -04001005 hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) {
Jeff Layton5acfec22010-08-02 17:43:54 -04001006 if (!d_unhashed(dentry) || IS_ROOT(dentry)) {
Nick Piggin873feea2011-01-07 17:50:06 +11001007 spin_unlock(&inode->i_lock);
Jeff Layton5acfec22010-08-02 17:43:54 -04001008 return true;
1009 }
1010 }
Nick Piggin873feea2011-01-07 17:50:06 +11001011 spin_unlock(&inode->i_lock);
Jeff Layton5acfec22010-08-02 17:43:54 -04001012 return false;
1013}
1014
Jeff Laytoncc0bad72009-06-25 00:56:52 -04001015/* Given fattrs, get a corresponding inode */
1016struct inode *
1017cifs_iget(struct super_block *sb, struct cifs_fattr *fattr)
1018{
1019 unsigned long hash;
1020 struct inode *inode;
1021
Jeff Layton3d694382010-05-11 14:59:55 -04001022retry_iget5_locked:
Joe Perchesf96637b2013-05-04 22:12:25 -05001023 cifs_dbg(FYI, "looking for uniqueid=%llu\n", fattr->cf_uniqueid);
Jeff Laytoncc0bad72009-06-25 00:56:52 -04001024
1025 /* hash down to 32-bits on 32-bit arch */
1026 hash = cifs_uniqueid_to_ino_t(fattr->cf_uniqueid);
1027
1028 inode = iget5_locked(sb, hash, cifs_find_inode, cifs_init_inode, fattr);
Jeff Laytoncc0bad72009-06-25 00:56:52 -04001029 if (inode) {
Jeff Layton5acfec22010-08-02 17:43:54 -04001030 /* was there a potentially problematic inode collision? */
Jeff Layton3d694382010-05-11 14:59:55 -04001031 if (fattr->cf_flags & CIFS_FATTR_INO_COLLISION) {
Jeff Layton3d694382010-05-11 14:59:55 -04001032 fattr->cf_flags &= ~CIFS_FATTR_INO_COLLISION;
Jeff Layton5acfec22010-08-02 17:43:54 -04001033
1034 if (inode_has_hashed_dentries(inode)) {
1035 cifs_autodisable_serverino(CIFS_SB(sb));
1036 iput(inode);
1037 fattr->cf_uniqueid = iunique(sb, ROOT_I);
1038 goto retry_iget5_locked;
1039 }
Jeff Layton3d694382010-05-11 14:59:55 -04001040 }
1041
Jeff Laytoncc0bad72009-06-25 00:56:52 -04001042 cifs_fattr_to_inode(inode, fattr);
Linus Torvalds1751e8a2017-11-27 13:05:09 -08001043 if (sb->s_flags & SB_NOATIME)
Jeff Laytoncc0bad72009-06-25 00:56:52 -04001044 inode->i_flags |= S_NOATIME | S_NOCMTIME;
1045 if (inode->i_state & I_NEW) {
1046 inode->i_ino = hash;
Steve French0ccd4802010-07-16 04:31:02 +00001047#ifdef CONFIG_CIFS_FSCACHE
Suresh Jayaraman9451a9a2010-07-05 18:12:45 +05301048 /* initialize per-inode cache cookie pointer */
1049 CIFS_I(inode)->fscache = NULL;
Steve French0ccd4802010-07-16 04:31:02 +00001050#endif
Jeff Laytoncc0bad72009-06-25 00:56:52 -04001051 unlock_new_inode(inode);
1052 }
1053 }
1054
1055 return inode;
1056}
1057
Linus Torvalds1da177e2005-04-16 15:20:36 -07001058/* gets root inode */
Shirish Pargaonkar9b6763e2011-02-21 23:56:59 -06001059struct inode *cifs_root_iget(struct super_block *sb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001060{
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +04001061 unsigned int xid;
Jeff Layton0d424ad2010-09-20 16:01:35 -07001062 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
Jeff Laytoncc0bad72009-06-25 00:56:52 -04001063 struct inode *inode = NULL;
David Howellsce634ab2008-02-07 00:15:33 -08001064 long rc;
Steve French96daf2b2011-05-27 04:34:02 +00001065 struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
Aurelien Aptela6b50582016-05-25 19:59:09 +02001066 char *path = NULL;
1067 int len;
1068
1069 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH)
1070 && cifs_sb->prepath) {
1071 len = strlen(cifs_sb->prepath);
1072 path = kzalloc(len + 2 /* leading sep + null */, GFP_KERNEL);
1073 if (path == NULL)
1074 return ERR_PTR(-ENOMEM);
1075 path[0] = '/';
1076 memcpy(path+1, cifs_sb->prepath, len);
1077 } else {
1078 path = kstrdup("", GFP_KERNEL);
1079 if (path == NULL)
1080 return ERR_PTR(-ENOMEM);
1081 }
David Howellsce634ab2008-02-07 00:15:33 -08001082
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +04001083 xid = get_xid();
Steve Frenchb5b374e2014-10-06 01:01:03 -05001084 if (tcon->unix_ext) {
Aurelien Aptela6b50582016-05-25 19:59:09 +02001085 rc = cifs_get_inode_info_unix(&inode, path, sb, xid);
Steve Frenchb5b374e2014-10-06 01:01:03 -05001086 /* some servers mistakenly claim POSIX support */
1087 if (rc != -EOPNOTSUPP)
1088 goto iget_no_retry;
1089 cifs_dbg(VFS, "server does not support POSIX extensions");
1090 tcon->unix_ext = false;
1091 }
Jeff Layton0b8f18e2009-07-09 01:46:37 -04001092
Aurelien Aptela6b50582016-05-25 19:59:09 +02001093 convert_delimiter(path, CIFS_DIR_SEP(cifs_sb));
1094 rc = cifs_get_inode_info(&inode, path, NULL, sb, xid, NULL);
Steve Frenchb5b374e2014-10-06 01:01:03 -05001095
1096iget_no_retry:
Oskar Schirmera7851ce2010-11-10 21:06:13 +00001097 if (!inode) {
1098 inode = ERR_PTR(rc);
1099 goto out;
1100 }
Jeff Laytoncc0bad72009-06-25 00:56:52 -04001101
Steve French0ccd4802010-07-16 04:31:02 +00001102#ifdef CONFIG_CIFS_FSCACHE
Suresh Jayaramand03382c2010-07-05 18:12:27 +05301103 /* populate tcon->resource_id */
Jeff Layton0d424ad2010-09-20 16:01:35 -07001104 tcon->resource_id = CIFS_I(inode)->uniqueid;
Steve French0ccd4802010-07-16 04:31:02 +00001105#endif
Suresh Jayaramand03382c2010-07-05 18:12:27 +05301106
Aurelien Aptelb327a712018-01-24 13:46:10 +01001107 if (rc && tcon->pipe) {
Joe Perchesf96637b2013-05-04 22:12:25 -05001108 cifs_dbg(FYI, "ipc connection - fake read inode\n");
Steve Frenchb7ca6922012-08-03 08:43:01 -05001109 spin_lock(&inode->i_lock);
Steve French7f8ed422007-09-28 22:28:55 +00001110 inode->i_mode |= S_IFDIR;
Miklos Szeredibfe86842011-10-28 14:13:29 +02001111 set_nlink(inode, 2);
Steve French7f8ed422007-09-28 22:28:55 +00001112 inode->i_op = &cifs_ipc_inode_ops;
1113 inode->i_fop = &simple_dir_operations;
1114 inode->i_uid = cifs_sb->mnt_uid;
1115 inode->i_gid = cifs_sb->mnt_gid;
Steve Frenchb7ca6922012-08-03 08:43:01 -05001116 spin_unlock(&inode->i_lock);
Steve Frenchad661332008-08-12 14:14:40 +00001117 } else if (rc) {
David Howellsce634ab2008-02-07 00:15:33 -08001118 iget_failed(inode);
Oskar Schirmera7851ce2010-11-10 21:06:13 +00001119 inode = ERR_PTR(rc);
Steve French7f8ed422007-09-28 22:28:55 +00001120 }
1121
Oskar Schirmera7851ce2010-11-10 21:06:13 +00001122out:
Aurelien Aptela6b50582016-05-25 19:59:09 +02001123 kfree(path);
Phillip Potter31cd1062018-03-17 21:06:56 +00001124 free_xid(xid);
David Howellsce634ab2008-02-07 00:15:33 -08001125 return inode;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001126}
1127
Pavel Shilovskyed6875e2012-09-18 16:20:25 -07001128int
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +04001129cifs_set_file_info(struct inode *inode, struct iattr *attrs, unsigned int xid,
Pavel Shilovskyed6875e2012-09-18 16:20:25 -07001130 char *full_path, __u32 dosattr)
Steve French388e57b2008-09-16 23:50:58 +00001131{
Steve French388e57b2008-09-16 23:50:58 +00001132 bool set_time = false;
Steve French388e57b2008-09-16 23:50:58 +00001133 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
Pavel Shilovsky6bdf6db2012-09-18 16:20:32 -07001134 struct TCP_Server_Info *server;
Steve French388e57b2008-09-16 23:50:58 +00001135 FILE_BASIC_INFO info_buf;
1136
Steve French1adcb712009-02-25 14:19:56 +00001137 if (attrs == NULL)
1138 return -EINVAL;
1139
Pavel Shilovsky6bdf6db2012-09-18 16:20:32 -07001140 server = cifs_sb_master_tcon(cifs_sb)->ses->server;
1141 if (!server->ops->set_file_info)
1142 return -ENOSYS;
1143
Steve Frenchfd09b7d2018-08-02 20:28:18 -05001144 info_buf.Pad = 0;
1145
Steve French388e57b2008-09-16 23:50:58 +00001146 if (attrs->ia_valid & ATTR_ATIME) {
1147 set_time = true;
1148 info_buf.LastAccessTime =
Arnd Bergmann95390202018-06-19 17:27:58 +02001149 cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_atime));
Steve French388e57b2008-09-16 23:50:58 +00001150 } else
1151 info_buf.LastAccessTime = 0;
1152
1153 if (attrs->ia_valid & ATTR_MTIME) {
1154 set_time = true;
1155 info_buf.LastWriteTime =
Arnd Bergmann95390202018-06-19 17:27:58 +02001156 cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_mtime));
Steve French388e57b2008-09-16 23:50:58 +00001157 } else
1158 info_buf.LastWriteTime = 0;
1159
1160 /*
1161 * Samba throws this field away, but windows may actually use it.
1162 * Do not set ctime unless other time stamps are changed explicitly
1163 * (i.e. by utimes()) since we would then have a mix of client and
1164 * server times.
1165 */
1166 if (set_time && (attrs->ia_valid & ATTR_CTIME)) {
Joe Perchesf96637b2013-05-04 22:12:25 -05001167 cifs_dbg(FYI, "CIFS - CTIME changed\n");
Steve French388e57b2008-09-16 23:50:58 +00001168 info_buf.ChangeTime =
Arnd Bergmann95390202018-06-19 17:27:58 +02001169 cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_ctime));
Steve French388e57b2008-09-16 23:50:58 +00001170 } else
1171 info_buf.ChangeTime = 0;
1172
1173 info_buf.CreationTime = 0; /* don't change */
1174 info_buf.Attributes = cpu_to_le32(dosattr);
1175
Pavel Shilovsky6bdf6db2012-09-18 16:20:32 -07001176 return server->ops->set_file_info(inode, full_path, &info_buf, xid);
Steve French388e57b2008-09-16 23:50:58 +00001177}
1178
Jeff Laytona12a1ac2008-09-23 11:48:35 -04001179/*
Pavel Shilovskyed6875e2012-09-18 16:20:25 -07001180 * Open the given file (if it isn't already), set the DELETE_ON_CLOSE bit
Jeff Laytona12a1ac2008-09-23 11:48:35 -04001181 * and rename it to a random name that hopefully won't conflict with
1182 * anything else.
1183 */
Pavel Shilovskyed6875e2012-09-18 16:20:25 -07001184int
1185cifs_rename_pending_delete(const char *full_path, struct dentry *dentry,
1186 const unsigned int xid)
Jeff Laytona12a1ac2008-09-23 11:48:35 -04001187{
1188 int oplock = 0;
1189 int rc;
Pavel Shilovskyd81b8a42014-01-16 15:53:36 +04001190 struct cifs_fid fid;
1191 struct cifs_open_parms oparms;
David Howells2b0143b2015-03-17 22:25:59 +00001192 struct inode *inode = d_inode(dentry);
Jeff Laytona12a1ac2008-09-23 11:48:35 -04001193 struct cifsInodeInfo *cifsInode = CIFS_I(inode);
1194 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
Jeff Layton7ffec372010-09-29 19:51:11 -04001195 struct tcon_link *tlink;
Steve French96daf2b2011-05-27 04:34:02 +00001196 struct cifs_tcon *tcon;
Steve French32709582008-10-20 00:44:19 +00001197 __u32 dosattr, origattr;
1198 FILE_BASIC_INFO *info_buf = NULL;
Jeff Laytona12a1ac2008-09-23 11:48:35 -04001199
Jeff Layton7ffec372010-09-29 19:51:11 -04001200 tlink = cifs_sb_tlink(cifs_sb);
1201 if (IS_ERR(tlink))
1202 return PTR_ERR(tlink);
1203 tcon = tlink_tcon(tlink);
1204
Sachin Prabhuc483a982013-03-05 19:25:56 +00001205 /*
1206 * We cannot rename the file if the server doesn't support
1207 * CAP_INFOLEVEL_PASSTHRU
1208 */
1209 if (!(tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)) {
1210 rc = -EBUSY;
1211 goto out;
1212 }
1213
Pavel Shilovskyd81b8a42014-01-16 15:53:36 +04001214 oparms.tcon = tcon;
1215 oparms.cifs_sb = cifs_sb;
1216 oparms.desired_access = DELETE | FILE_WRITE_ATTRIBUTES;
1217 oparms.create_options = CREATE_NOT_DIR;
1218 oparms.disposition = FILE_OPEN;
1219 oparms.path = full_path;
1220 oparms.fid = &fid;
1221 oparms.reconnect = false;
1222
1223 rc = CIFS_open(xid, &oparms, &oplock, NULL);
Jeff Laytona12a1ac2008-09-23 11:48:35 -04001224 if (rc != 0)
1225 goto out;
1226
Steve French32709582008-10-20 00:44:19 +00001227 origattr = cifsInode->cifsAttrs;
1228 if (origattr == 0)
1229 origattr |= ATTR_NORMAL;
1230
1231 dosattr = origattr & ~ATTR_READONLY;
Jeff Laytona12a1ac2008-09-23 11:48:35 -04001232 if (dosattr == 0)
1233 dosattr |= ATTR_NORMAL;
1234 dosattr |= ATTR_HIDDEN;
1235
Steve French32709582008-10-20 00:44:19 +00001236 /* set ATTR_HIDDEN and clear ATTR_READONLY, but only if needed */
1237 if (dosattr != origattr) {
1238 info_buf = kzalloc(sizeof(*info_buf), GFP_KERNEL);
1239 if (info_buf == NULL) {
1240 rc = -ENOMEM;
1241 goto out_close;
1242 }
1243 info_buf->Attributes = cpu_to_le32(dosattr);
Pavel Shilovskyd81b8a42014-01-16 15:53:36 +04001244 rc = CIFSSMBSetFileInfo(xid, tcon, info_buf, fid.netfid,
Steve French32709582008-10-20 00:44:19 +00001245 current->tgid);
1246 /* although we would like to mark the file hidden
1247 if that fails we will still try to rename it */
Sachin Prabhu72d282d2013-03-05 19:25:55 +00001248 if (!rc)
Steve French32709582008-10-20 00:44:19 +00001249 cifsInode->cifsAttrs = dosattr;
1250 else
1251 dosattr = origattr; /* since not able to change them */
Jeff Laytona12a1ac2008-09-23 11:48:35 -04001252 }
Jeff Laytona12a1ac2008-09-23 11:48:35 -04001253
Jeff Laytondd1db2d2008-10-16 19:27:12 -04001254 /* rename the file */
Pavel Shilovskyd81b8a42014-01-16 15:53:36 +04001255 rc = CIFSSMBRenameOpenFile(xid, tcon, fid.netfid, NULL,
1256 cifs_sb->local_nls,
Steve French2baa2682014-09-27 02:19:01 -05001257 cifs_remap(cifs_sb));
Steve French32709582008-10-20 00:44:19 +00001258 if (rc != 0) {
Sachin Prabhu47c78f42013-03-11 13:08:49 +00001259 rc = -EBUSY;
Steve French32709582008-10-20 00:44:19 +00001260 goto undo_setattr;
1261 }
Jeff Layton6d22f092008-09-23 11:48:35 -04001262
Steve French32709582008-10-20 00:44:19 +00001263 /* try to set DELETE_ON_CLOSE */
Jeff Laytonaff8d5c2014-04-30 09:31:45 -04001264 if (!test_bit(CIFS_INO_DELETE_PENDING, &cifsInode->flags)) {
Pavel Shilovskyd81b8a42014-01-16 15:53:36 +04001265 rc = CIFSSMBSetFileDisposition(xid, tcon, true, fid.netfid,
Steve French32709582008-10-20 00:44:19 +00001266 current->tgid);
1267 /*
1268 * some samba versions return -ENOENT when we try to set the
1269 * file disposition here. Likely a samba bug, but work around
1270 * it for now. This means that some cifsXXX files may hang
1271 * around after they shouldn't.
1272 *
1273 * BB: remove this hack after more servers have the fix
1274 */
1275 if (rc == -ENOENT)
1276 rc = 0;
1277 else if (rc != 0) {
Sachin Prabhu47c78f42013-03-11 13:08:49 +00001278 rc = -EBUSY;
Steve French32709582008-10-20 00:44:19 +00001279 goto undo_rename;
1280 }
Jeff Laytonaff8d5c2014-04-30 09:31:45 -04001281 set_bit(CIFS_INO_DELETE_PENDING, &cifsInode->flags);
Steve French32709582008-10-20 00:44:19 +00001282 }
Jeff Layton7ce86d52008-09-24 11:32:59 -04001283
Jeff Laytona12a1ac2008-09-23 11:48:35 -04001284out_close:
Pavel Shilovskyd81b8a42014-01-16 15:53:36 +04001285 CIFSSMBClose(xid, tcon, fid.netfid);
Jeff Laytona12a1ac2008-09-23 11:48:35 -04001286out:
Steve French32709582008-10-20 00:44:19 +00001287 kfree(info_buf);
Jeff Layton7ffec372010-09-29 19:51:11 -04001288 cifs_put_tlink(tlink);
Jeff Laytona12a1ac2008-09-23 11:48:35 -04001289 return rc;
Steve French32709582008-10-20 00:44:19 +00001290
1291 /*
1292 * reset everything back to the original state. Don't bother
1293 * dealing with errors here since we can't do anything about
1294 * them anyway.
1295 */
1296undo_rename:
Pavel Shilovskyd81b8a42014-01-16 15:53:36 +04001297 CIFSSMBRenameOpenFile(xid, tcon, fid.netfid, dentry->d_name.name,
Steve French2baa2682014-09-27 02:19:01 -05001298 cifs_sb->local_nls, cifs_remap(cifs_sb));
Steve French32709582008-10-20 00:44:19 +00001299undo_setattr:
1300 if (dosattr != origattr) {
1301 info_buf->Attributes = cpu_to_le32(origattr);
Pavel Shilovskyd81b8a42014-01-16 15:53:36 +04001302 if (!CIFSSMBSetFileInfo(xid, tcon, info_buf, fid.netfid,
Steve French32709582008-10-20 00:44:19 +00001303 current->tgid))
1304 cifsInode->cifsAttrs = origattr;
1305 }
1306
1307 goto out_close;
Jeff Laytona12a1ac2008-09-23 11:48:35 -04001308}
1309
Steve Frenchb7ca6922012-08-03 08:43:01 -05001310/* copied from fs/nfs/dir.c with small changes */
1311static void
1312cifs_drop_nlink(struct inode *inode)
1313{
1314 spin_lock(&inode->i_lock);
1315 if (inode->i_nlink > 0)
1316 drop_nlink(inode);
1317 spin_unlock(&inode->i_lock);
1318}
Steve Frenchff694522009-04-20 19:45:13 +00001319
1320/*
David Howells2b0143b2015-03-17 22:25:59 +00001321 * If d_inode(dentry) is null (usually meaning the cached dentry
Steve Frenchff694522009-04-20 19:45:13 +00001322 * is a negative dentry) then we would attempt a standard SMB delete, but
André Goddard Rosaaf901ca2009-11-14 13:09:05 -02001323 * if that fails we can not attempt the fall back mechanisms on EACCESS
1324 * but will return the EACCESS to the caller. Note that the VFS does not call
Steve Frenchff694522009-04-20 19:45:13 +00001325 * unlink on negative dentries currently.
1326 */
Jeff Layton5f0319a2008-09-16 14:05:16 -04001327int cifs_unlink(struct inode *dir, struct dentry *dentry)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001328{
1329 int rc = 0;
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +04001330 unsigned int xid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001331 char *full_path = NULL;
David Howells2b0143b2015-03-17 22:25:59 +00001332 struct inode *inode = d_inode(dentry);
Steve Frenchff694522009-04-20 19:45:13 +00001333 struct cifsInodeInfo *cifs_inode;
Jeff Layton5f0319a2008-09-16 14:05:16 -04001334 struct super_block *sb = dir->i_sb;
1335 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
Jeff Layton7ffec372010-09-29 19:51:11 -04001336 struct tcon_link *tlink;
Steve French96daf2b2011-05-27 04:34:02 +00001337 struct cifs_tcon *tcon;
Pavel Shilovskyed6875e2012-09-18 16:20:25 -07001338 struct TCP_Server_Info *server;
Steve French60502472008-10-07 18:42:52 +00001339 struct iattr *attrs = NULL;
1340 __u32 dosattr = 0, origattr = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001341
Joe Perchesf96637b2013-05-04 22:12:25 -05001342 cifs_dbg(FYI, "cifs_unlink, dir=0x%p, dentry=0x%p\n", dir, dentry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001343
Jeff Layton7ffec372010-09-29 19:51:11 -04001344 tlink = cifs_sb_tlink(cifs_sb);
1345 if (IS_ERR(tlink))
1346 return PTR_ERR(tlink);
1347 tcon = tlink_tcon(tlink);
Pavel Shilovskyed6875e2012-09-18 16:20:25 -07001348 server = tcon->ses->server;
Jeff Layton7ffec372010-09-29 19:51:11 -04001349
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +04001350 xid = get_xid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001351
Jeff Layton5f0319a2008-09-16 14:05:16 -04001352 /* Unlink can be called from rename so we can not take the
1353 * sb->s_vfs_rename_mutex here */
1354 full_path = build_path_from_dentry(dentry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001355 if (full_path == NULL) {
Suresh Jayaraman0f3bc092009-06-25 18:12:34 +05301356 rc = -ENOMEM;
Jeff Layton7ffec372010-09-29 19:51:11 -04001357 goto unlink_out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001358 }
Steve French2d785a52007-07-15 01:48:57 +00001359
Pavel Shilovsky29e20f92012-07-13 13:58:14 +04001360 if (cap_unix(tcon->ses) && (CIFS_UNIX_POSIX_PATH_OPS_CAP &
1361 le64_to_cpu(tcon->fsUnixInfo.Capability))) {
Jeff Layton5f0319a2008-09-16 14:05:16 -04001362 rc = CIFSPOSIXDelFile(xid, tcon, full_path,
Steve French2d785a52007-07-15 01:48:57 +00001363 SMB_POSIX_UNLINK_FILE_TARGET, cifs_sb->local_nls,
Steve French2baa2682014-09-27 02:19:01 -05001364 cifs_remap(cifs_sb));
Joe Perchesf96637b2013-05-04 22:12:25 -05001365 cifs_dbg(FYI, "posix del rc %d\n", rc);
Steve French2d785a52007-07-15 01:48:57 +00001366 if ((rc == 0) || (rc == -ENOENT))
1367 goto psx_del_no_retry;
1368 }
1369
Steve French60502472008-10-07 18:42:52 +00001370retry_std_delete:
Pavel Shilovskyed6875e2012-09-18 16:20:25 -07001371 if (!server->ops->unlink) {
1372 rc = -ENOSYS;
1373 goto psx_del_no_retry;
1374 }
1375
1376 rc = server->ops->unlink(xid, tcon, full_path, cifs_sb);
Steve French60502472008-10-07 18:42:52 +00001377
Steve French2d785a52007-07-15 01:48:57 +00001378psx_del_no_retry:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001379 if (!rc) {
Jeff Layton5f0319a2008-09-16 14:05:16 -04001380 if (inode)
Steve Frenchb7ca6922012-08-03 08:43:01 -05001381 cifs_drop_nlink(inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001382 } else if (rc == -ENOENT) {
Jeff Layton5f0319a2008-09-16 14:05:16 -04001383 d_drop(dentry);
Sachin Prabhu47c78f42013-03-11 13:08:49 +00001384 } else if (rc == -EBUSY) {
Pavel Shilovskyed6875e2012-09-18 16:20:25 -07001385 if (server->ops->rename_pending_delete) {
1386 rc = server->ops->rename_pending_delete(full_path,
1387 dentry, xid);
1388 if (rc == 0)
1389 cifs_drop_nlink(inode);
1390 }
Steve Frenchff694522009-04-20 19:45:13 +00001391 } else if ((rc == -EACCES) && (dosattr == 0) && inode) {
Steve French388e57b2008-09-16 23:50:58 +00001392 attrs = kzalloc(sizeof(*attrs), GFP_KERNEL);
1393 if (attrs == NULL) {
1394 rc = -ENOMEM;
1395 goto out_reval;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001396 }
Steve French388e57b2008-09-16 23:50:58 +00001397
1398 /* try to reset dos attributes */
Steve Frenchff694522009-04-20 19:45:13 +00001399 cifs_inode = CIFS_I(inode);
1400 origattr = cifs_inode->cifsAttrs;
Steve French60502472008-10-07 18:42:52 +00001401 if (origattr == 0)
1402 origattr |= ATTR_NORMAL;
1403 dosattr = origattr & ~ATTR_READONLY;
Steve French388e57b2008-09-16 23:50:58 +00001404 if (dosattr == 0)
1405 dosattr |= ATTR_NORMAL;
1406 dosattr |= ATTR_HIDDEN;
1407
1408 rc = cifs_set_file_info(inode, attrs, xid, full_path, dosattr);
Steve French388e57b2008-09-16 23:50:58 +00001409 if (rc != 0)
1410 goto out_reval;
Steve French60502472008-10-07 18:42:52 +00001411
1412 goto retry_std_delete;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001413 }
Steve French60502472008-10-07 18:42:52 +00001414
1415 /* undo the setattr if we errored out and it's needed */
1416 if (rc != 0 && dosattr != 0)
1417 cifs_set_file_info(inode, attrs, xid, full_path, origattr);
1418
Steve French388e57b2008-09-16 23:50:58 +00001419out_reval:
Jeff Layton5f0319a2008-09-16 14:05:16 -04001420 if (inode) {
Steve Frenchff694522009-04-20 19:45:13 +00001421 cifs_inode = CIFS_I(inode);
1422 cifs_inode->time = 0; /* will force revalidate to get info
Steve Frenchb2aeb9d2005-05-17 13:16:18 -05001423 when needed */
Deepa Dinamanie37fea52017-05-08 15:59:16 -07001424 inode->i_ctime = current_time(inode);
Steve Frenchb2aeb9d2005-05-17 13:16:18 -05001425 }
Deepa Dinamanie37fea52017-05-08 15:59:16 -07001426 dir->i_ctime = dir->i_mtime = current_time(dir);
Steve Frenchff694522009-04-20 19:45:13 +00001427 cifs_inode = CIFS_I(dir);
Steve French60502472008-10-07 18:42:52 +00001428 CIFS_I(dir)->time = 0; /* force revalidate of dir as well */
Jeff Layton7ffec372010-09-29 19:51:11 -04001429unlink_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001430 kfree(full_path);
Steve French60502472008-10-07 18:42:52 +00001431 kfree(attrs);
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +04001432 free_xid(xid);
Jeff Layton7ffec372010-09-29 19:51:11 -04001433 cifs_put_tlink(tlink);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001434 return rc;
1435}
1436
Pavel Shilovskyff691e92012-07-13 14:04:46 +04001437static int
Jeff Layton101b92d2012-09-19 06:22:45 -07001438cifs_mkdir_qinfo(struct inode *parent, struct dentry *dentry, umode_t mode,
Pavel Shilovskyff691e92012-07-13 14:04:46 +04001439 const char *full_path, struct cifs_sb_info *cifs_sb,
1440 struct cifs_tcon *tcon, const unsigned int xid)
1441{
1442 int rc = 0;
Jeff Layton101b92d2012-09-19 06:22:45 -07001443 struct inode *inode = NULL;
Pavel Shilovskyff691e92012-07-13 14:04:46 +04001444
1445 if (tcon->unix_ext)
Jeff Layton101b92d2012-09-19 06:22:45 -07001446 rc = cifs_get_inode_info_unix(&inode, full_path, parent->i_sb,
Pavel Shilovskyff691e92012-07-13 14:04:46 +04001447 xid);
1448 else
Jeff Layton101b92d2012-09-19 06:22:45 -07001449 rc = cifs_get_inode_info(&inode, full_path, NULL, parent->i_sb,
1450 xid, NULL);
1451
Pavel Shilovskyff691e92012-07-13 14:04:46 +04001452 if (rc)
1453 return rc;
1454
Pavel Shilovskyff691e92012-07-13 14:04:46 +04001455 /*
1456 * setting nlink not necessary except in cases where we failed to get it
Jeff Layton101b92d2012-09-19 06:22:45 -07001457 * from the server or was set bogus. Also, since this is a brand new
1458 * inode, no need to grab the i_lock before setting the i_nlink.
Pavel Shilovskyff691e92012-07-13 14:04:46 +04001459 */
Jeff Layton101b92d2012-09-19 06:22:45 -07001460 if (inode->i_nlink < 2)
1461 set_nlink(inode, 2);
Pavel Shilovskyff691e92012-07-13 14:04:46 +04001462 mode &= ~current_umask();
1463 /* must turn on setgid bit if parent dir has it */
Jeff Layton101b92d2012-09-19 06:22:45 -07001464 if (parent->i_mode & S_ISGID)
Pavel Shilovskyff691e92012-07-13 14:04:46 +04001465 mode |= S_ISGID;
1466
1467 if (tcon->unix_ext) {
1468 struct cifs_unix_set_info_args args = {
1469 .mode = mode,
1470 .ctime = NO_CHANGE_64,
1471 .atime = NO_CHANGE_64,
1472 .mtime = NO_CHANGE_64,
1473 .device = 0,
1474 };
1475 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
Eric W. Biederman49418b22013-02-06 00:57:56 -08001476 args.uid = current_fsuid();
Jeff Layton101b92d2012-09-19 06:22:45 -07001477 if (parent->i_mode & S_ISGID)
Eric W. Biederman49418b22013-02-06 00:57:56 -08001478 args.gid = parent->i_gid;
Pavel Shilovskyff691e92012-07-13 14:04:46 +04001479 else
Eric W. Biederman49418b22013-02-06 00:57:56 -08001480 args.gid = current_fsgid();
Pavel Shilovskyff691e92012-07-13 14:04:46 +04001481 } else {
Eric W. Biederman49418b22013-02-06 00:57:56 -08001482 args.uid = INVALID_UID; /* no change */
1483 args.gid = INVALID_GID; /* no change */
Pavel Shilovskyff691e92012-07-13 14:04:46 +04001484 }
1485 CIFSSMBUnixSetPathInfo(xid, tcon, full_path, &args,
1486 cifs_sb->local_nls,
Steve French2baa2682014-09-27 02:19:01 -05001487 cifs_remap(cifs_sb));
Pavel Shilovskyff691e92012-07-13 14:04:46 +04001488 } else {
Pavel Shilovskyf4367202012-03-17 11:41:12 +03001489 struct TCP_Server_Info *server = tcon->ses->server;
Pavel Shilovskyff691e92012-07-13 14:04:46 +04001490 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) &&
Pavel Shilovskyf4367202012-03-17 11:41:12 +03001491 (mode & S_IWUGO) == 0 && server->ops->mkdir_setinfo)
Jeff Layton101b92d2012-09-19 06:22:45 -07001492 server->ops->mkdir_setinfo(inode, full_path, cifs_sb,
Pavel Shilovskyf4367202012-03-17 11:41:12 +03001493 tcon, xid);
Jeff Layton101b92d2012-09-19 06:22:45 -07001494 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)
1495 inode->i_mode = (mode | S_IFDIR);
Pavel Shilovskyff691e92012-07-13 14:04:46 +04001496
Jeff Layton101b92d2012-09-19 06:22:45 -07001497 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
1498 inode->i_uid = current_fsuid();
1499 if (inode->i_mode & S_ISGID)
1500 inode->i_gid = parent->i_gid;
1501 else
1502 inode->i_gid = current_fsgid();
Pavel Shilovskyff691e92012-07-13 14:04:46 +04001503 }
1504 }
Jeff Layton101b92d2012-09-19 06:22:45 -07001505 d_instantiate(dentry, inode);
Pavel Shilovskyff691e92012-07-13 14:04:46 +04001506 return rc;
1507}
1508
1509static int
1510cifs_posix_mkdir(struct inode *inode, struct dentry *dentry, umode_t mode,
1511 const char *full_path, struct cifs_sb_info *cifs_sb,
1512 struct cifs_tcon *tcon, const unsigned int xid)
1513{
1514 int rc = 0;
1515 u32 oplock = 0;
1516 FILE_UNIX_BASIC_INFO *info = NULL;
1517 struct inode *newinode = NULL;
1518 struct cifs_fattr fattr;
1519
1520 info = kzalloc(sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL);
1521 if (info == NULL) {
1522 rc = -ENOMEM;
1523 goto posix_mkdir_out;
1524 }
1525
1526 mode &= ~current_umask();
1527 rc = CIFSPOSIXCreate(xid, tcon, SMB_O_DIRECTORY | SMB_O_CREAT, mode,
1528 NULL /* netfid */, info, &oplock, full_path,
Steve French2baa2682014-09-27 02:19:01 -05001529 cifs_sb->local_nls, cifs_remap(cifs_sb));
Pavel Shilovskyff691e92012-07-13 14:04:46 +04001530 if (rc == -EOPNOTSUPP)
1531 goto posix_mkdir_out;
1532 else if (rc) {
Joe Perchesf96637b2013-05-04 22:12:25 -05001533 cifs_dbg(FYI, "posix mkdir returned 0x%x\n", rc);
Pavel Shilovskyff691e92012-07-13 14:04:46 +04001534 d_drop(dentry);
1535 goto posix_mkdir_out;
1536 }
1537
1538 if (info->Type == cpu_to_le32(-1))
1539 /* no return info, go query for it */
1540 goto posix_mkdir_get_info;
1541 /*
1542 * BB check (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID ) to see if
1543 * need to set uid/gid.
1544 */
1545
1546 cifs_unix_basic_to_fattr(&fattr, info, cifs_sb);
1547 cifs_fill_uniqueid(inode->i_sb, &fattr);
1548 newinode = cifs_iget(inode->i_sb, &fattr);
1549 if (!newinode)
1550 goto posix_mkdir_get_info;
1551
1552 d_instantiate(dentry, newinode);
1553
1554#ifdef CONFIG_CIFS_DEBUG2
Al Viro35c265e2014-08-19 20:25:34 -04001555 cifs_dbg(FYI, "instantiated dentry %p %pd to inode %p\n",
1556 dentry, dentry, newinode);
Pavel Shilovskyff691e92012-07-13 14:04:46 +04001557
1558 if (newinode->i_nlink != 2)
Joe Perchesf96637b2013-05-04 22:12:25 -05001559 cifs_dbg(FYI, "unexpected number of links %d\n",
1560 newinode->i_nlink);
Pavel Shilovskyff691e92012-07-13 14:04:46 +04001561#endif
1562
1563posix_mkdir_out:
1564 kfree(info);
1565 return rc;
1566posix_mkdir_get_info:
1567 rc = cifs_mkdir_qinfo(inode, dentry, mode, full_path, cifs_sb, tcon,
1568 xid);
1569 goto posix_mkdir_out;
1570}
1571
Al Viro18bb1db2011-07-26 01:41:39 -04001572int cifs_mkdir(struct inode *inode, struct dentry *direntry, umode_t mode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001573{
Pavel Shilovskyff691e92012-07-13 14:04:46 +04001574 int rc = 0;
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +04001575 unsigned int xid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001576 struct cifs_sb_info *cifs_sb;
Jeff Layton7ffec372010-09-29 19:51:11 -04001577 struct tcon_link *tlink;
Pavel Shilovsky29e20f92012-07-13 13:58:14 +04001578 struct cifs_tcon *tcon;
Pavel Shilovskyf4367202012-03-17 11:41:12 +03001579 struct TCP_Server_Info *server;
Pavel Shilovskyff691e92012-07-13 14:04:46 +04001580 char *full_path;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001581
Joe Perchesf96637b2013-05-04 22:12:25 -05001582 cifs_dbg(FYI, "In cifs_mkdir, mode = 0x%hx inode = 0x%p\n",
1583 mode, inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001584
Linus Torvalds1da177e2005-04-16 15:20:36 -07001585 cifs_sb = CIFS_SB(inode->i_sb);
Jeff Layton7ffec372010-09-29 19:51:11 -04001586 tlink = cifs_sb_tlink(cifs_sb);
1587 if (IS_ERR(tlink))
1588 return PTR_ERR(tlink);
Pavel Shilovsky29e20f92012-07-13 13:58:14 +04001589 tcon = tlink_tcon(tlink);
Jeff Layton7ffec372010-09-29 19:51:11 -04001590
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +04001591 xid = get_xid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001592
Steve French7f573562005-08-30 11:32:14 -07001593 full_path = build_path_from_dentry(direntry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001594 if (full_path == NULL) {
Suresh Jayaraman0f3bc092009-06-25 18:12:34 +05301595 rc = -ENOMEM;
Jeff Layton7ffec372010-09-29 19:51:11 -04001596 goto mkdir_out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001597 }
Steve French50c2f752007-07-13 00:33:32 +00001598
Steve Frenchbea851b2018-06-14 21:56:32 -05001599 server = tcon->ses->server;
1600
Steve Frenchbea851b2018-06-14 21:56:32 -05001601 if ((server->ops->posix_mkdir) && (tcon->posix_extensions)) {
1602 rc = server->ops->posix_mkdir(xid, inode, mode, tcon, full_path,
1603 cifs_sb);
1604 d_drop(direntry); /* for time being always refresh inode info */
1605 goto mkdir_out;
1606 }
Steve Frenchbea851b2018-06-14 21:56:32 -05001607
Pavel Shilovsky29e20f92012-07-13 13:58:14 +04001608 if (cap_unix(tcon->ses) && (CIFS_UNIX_POSIX_PATH_OPS_CAP &
1609 le64_to_cpu(tcon->fsUnixInfo.Capability))) {
Pavel Shilovskyff691e92012-07-13 14:04:46 +04001610 rc = cifs_posix_mkdir(inode, direntry, mode, full_path, cifs_sb,
1611 tcon, xid);
1612 if (rc != -EOPNOTSUPP)
Steve French2dd29d32007-04-23 22:07:35 +00001613 goto mkdir_out;
Steve Frenchfb8c4b12007-07-10 01:16:18 +00001614 }
Pavel Shilovskyff691e92012-07-13 14:04:46 +04001615
Pavel Shilovskyf4367202012-03-17 11:41:12 +03001616 if (!server->ops->mkdir) {
1617 rc = -ENOSYS;
1618 goto mkdir_out;
1619 }
1620
Linus Torvalds1da177e2005-04-16 15:20:36 -07001621 /* BB add setting the equivalent of mode via CreateX w/ACLs */
Pavel Shilovskyf4367202012-03-17 11:41:12 +03001622 rc = server->ops->mkdir(xid, tcon, full_path, cifs_sb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001623 if (rc) {
Joe Perchesf96637b2013-05-04 22:12:25 -05001624 cifs_dbg(FYI, "cifs_mkdir returned 0x%x\n", rc);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001625 d_drop(direntry);
Pavel Shilovskyff691e92012-07-13 14:04:46 +04001626 goto mkdir_out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001627 }
Pavel Shilovskyff691e92012-07-13 14:04:46 +04001628
1629 rc = cifs_mkdir_qinfo(inode, direntry, mode, full_path, cifs_sb, tcon,
1630 xid);
Steve Frenchfb8c4b12007-07-10 01:16:18 +00001631mkdir_out:
Pavel Shilovsky6de2ce42012-02-17 16:13:30 +03001632 /*
1633 * Force revalidate to get parent dir info when needed since cached
1634 * attributes are invalid now.
1635 */
1636 CIFS_I(inode)->time = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001637 kfree(full_path);
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +04001638 free_xid(xid);
Jeff Layton7ffec372010-09-29 19:51:11 -04001639 cifs_put_tlink(tlink);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001640 return rc;
1641}
1642
1643int cifs_rmdir(struct inode *inode, struct dentry *direntry)
1644{
1645 int rc = 0;
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +04001646 unsigned int xid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001647 struct cifs_sb_info *cifs_sb;
Jeff Layton7ffec372010-09-29 19:51:11 -04001648 struct tcon_link *tlink;
Pavel Shilovskyf958ca52012-07-10 16:14:18 +04001649 struct cifs_tcon *tcon;
1650 struct TCP_Server_Info *server;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001651 char *full_path = NULL;
1652 struct cifsInodeInfo *cifsInode;
1653
Joe Perchesf96637b2013-05-04 22:12:25 -05001654 cifs_dbg(FYI, "cifs_rmdir, inode = 0x%p\n", inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001655
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +04001656 xid = get_xid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001657
Steve French7f573562005-08-30 11:32:14 -07001658 full_path = build_path_from_dentry(direntry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001659 if (full_path == NULL) {
Suresh Jayaraman0f3bc092009-06-25 18:12:34 +05301660 rc = -ENOMEM;
Jeff Layton7ffec372010-09-29 19:51:11 -04001661 goto rmdir_exit;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001662 }
1663
Jeff Layton7ffec372010-09-29 19:51:11 -04001664 cifs_sb = CIFS_SB(inode->i_sb);
1665 tlink = cifs_sb_tlink(cifs_sb);
1666 if (IS_ERR(tlink)) {
1667 rc = PTR_ERR(tlink);
1668 goto rmdir_exit;
1669 }
Pavel Shilovskyf958ca52012-07-10 16:14:18 +04001670 tcon = tlink_tcon(tlink);
1671 server = tcon->ses->server;
Jeff Layton7ffec372010-09-29 19:51:11 -04001672
Pavel Shilovskyf958ca52012-07-10 16:14:18 +04001673 if (!server->ops->rmdir) {
1674 rc = -ENOSYS;
1675 cifs_put_tlink(tlink);
1676 goto rmdir_exit;
1677 }
1678
1679 rc = server->ops->rmdir(xid, tcon, full_path, cifs_sb);
Jeff Layton7ffec372010-09-29 19:51:11 -04001680 cifs_put_tlink(tlink);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001681
1682 if (!rc) {
David Howells2b0143b2015-03-17 22:25:59 +00001683 spin_lock(&d_inode(direntry)->i_lock);
1684 i_size_write(d_inode(direntry), 0);
1685 clear_nlink(d_inode(direntry));
1686 spin_unlock(&d_inode(direntry)->i_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001687 }
1688
David Howells2b0143b2015-03-17 22:25:59 +00001689 cifsInode = CIFS_I(d_inode(direntry));
Pavel Shilovsky6de2ce42012-02-17 16:13:30 +03001690 /* force revalidate to go get info when needed */
1691 cifsInode->time = 0;
Steve French42c245442009-01-13 22:03:55 +00001692
1693 cifsInode = CIFS_I(inode);
Pavel Shilovsky6de2ce42012-02-17 16:13:30 +03001694 /*
1695 * Force revalidate to get parent dir info when needed since cached
1696 * attributes are invalid now.
1697 */
1698 cifsInode->time = 0;
Steve French42c245442009-01-13 22:03:55 +00001699
David Howells2b0143b2015-03-17 22:25:59 +00001700 d_inode(direntry)->i_ctime = inode->i_ctime = inode->i_mtime =
Deepa Dinamanie37fea52017-05-08 15:59:16 -07001701 current_time(inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001702
Jeff Layton7ffec372010-09-29 19:51:11 -04001703rmdir_exit:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001704 kfree(full_path);
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +04001705 free_xid(xid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001706 return rc;
1707}
1708
Steve Frenchee2fd962008-09-23 18:23:33 +00001709static int
Pavel Shilovsky8ceb9842012-09-18 16:20:30 -07001710cifs_do_rename(const unsigned int xid, struct dentry *from_dentry,
1711 const char *from_path, struct dentry *to_dentry,
1712 const char *to_path)
Steve Frenchee2fd962008-09-23 18:23:33 +00001713{
1714 struct cifs_sb_info *cifs_sb = CIFS_SB(from_dentry->d_sb);
Jeff Layton7ffec372010-09-29 19:51:11 -04001715 struct tcon_link *tlink;
Pavel Shilovsky8ceb9842012-09-18 16:20:30 -07001716 struct cifs_tcon *tcon;
1717 struct TCP_Server_Info *server;
Pavel Shilovskyd81b8a42014-01-16 15:53:36 +04001718 struct cifs_fid fid;
1719 struct cifs_open_parms oparms;
Steve Frenchee2fd962008-09-23 18:23:33 +00001720 int oplock, rc;
1721
Jeff Layton7ffec372010-09-29 19:51:11 -04001722 tlink = cifs_sb_tlink(cifs_sb);
1723 if (IS_ERR(tlink))
1724 return PTR_ERR(tlink);
Pavel Shilovsky8ceb9842012-09-18 16:20:30 -07001725 tcon = tlink_tcon(tlink);
1726 server = tcon->ses->server;
1727
1728 if (!server->ops->rename)
1729 return -ENOSYS;
Jeff Layton7ffec372010-09-29 19:51:11 -04001730
Steve Frenchee2fd962008-09-23 18:23:33 +00001731 /* try path-based rename first */
Pavel Shilovsky8ceb9842012-09-18 16:20:30 -07001732 rc = server->ops->rename(xid, tcon, from_path, to_path, cifs_sb);
Steve Frenchee2fd962008-09-23 18:23:33 +00001733
1734 /*
Pavel Shilovsky8ceb9842012-09-18 16:20:30 -07001735 * Don't bother with rename by filehandle unless file is busy and
1736 * source. Note that cross directory moves do not work with
Steve Frenchee2fd962008-09-23 18:23:33 +00001737 * rename by filehandle to various Windows servers.
1738 */
Sachin Prabhu47c78f42013-03-11 13:08:49 +00001739 if (rc == 0 || rc != -EBUSY)
Jeff Layton7ffec372010-09-29 19:51:11 -04001740 goto do_rename_exit;
Steve Frenchee2fd962008-09-23 18:23:33 +00001741
Jeff Laytoned0e3ac2010-06-01 16:21:01 -04001742 /* open-file renames don't work across directories */
1743 if (to_dentry->d_parent != from_dentry->d_parent)
Jeff Layton7ffec372010-09-29 19:51:11 -04001744 goto do_rename_exit;
Jeff Laytoned0e3ac2010-06-01 16:21:01 -04001745
Pavel Shilovskyd81b8a42014-01-16 15:53:36 +04001746 oparms.tcon = tcon;
1747 oparms.cifs_sb = cifs_sb;
Steve Frenchee2fd962008-09-23 18:23:33 +00001748 /* open the file to be renamed -- we need DELETE perms */
Pavel Shilovskyd81b8a42014-01-16 15:53:36 +04001749 oparms.desired_access = DELETE;
1750 oparms.create_options = CREATE_NOT_DIR;
1751 oparms.disposition = FILE_OPEN;
1752 oparms.path = from_path;
1753 oparms.fid = &fid;
1754 oparms.reconnect = false;
1755
1756 rc = CIFS_open(xid, &oparms, &oplock, NULL);
Steve Frenchee2fd962008-09-23 18:23:33 +00001757 if (rc == 0) {
Pavel Shilovskyd81b8a42014-01-16 15:53:36 +04001758 rc = CIFSSMBRenameOpenFile(xid, tcon, fid.netfid,
Steve Frenchee2fd962008-09-23 18:23:33 +00001759 (const char *) to_dentry->d_name.name,
Steve French2baa2682014-09-27 02:19:01 -05001760 cifs_sb->local_nls, cifs_remap(cifs_sb));
Pavel Shilovskyd81b8a42014-01-16 15:53:36 +04001761 CIFSSMBClose(xid, tcon, fid.netfid);
Steve Frenchee2fd962008-09-23 18:23:33 +00001762 }
Jeff Layton7ffec372010-09-29 19:51:11 -04001763do_rename_exit:
1764 cifs_put_tlink(tlink);
Steve Frenchee2fd962008-09-23 18:23:33 +00001765 return rc;
1766}
1767
Pavel Shilovsky8ceb9842012-09-18 16:20:30 -07001768int
Miklos Szeredi7c33d592014-07-23 15:15:36 +02001769cifs_rename2(struct inode *source_dir, struct dentry *source_dentry,
1770 struct inode *target_dir, struct dentry *target_dentry,
1771 unsigned int flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001772{
Pavel Shilovsky8ceb9842012-09-18 16:20:30 -07001773 char *from_name = NULL;
1774 char *to_name = NULL;
Jeff Layton639e7a92010-09-03 11:50:09 -04001775 struct cifs_sb_info *cifs_sb;
Jeff Layton7ffec372010-09-29 19:51:11 -04001776 struct tcon_link *tlink;
Steve French96daf2b2011-05-27 04:34:02 +00001777 struct cifs_tcon *tcon;
Steve Frenchee2fd962008-09-23 18:23:33 +00001778 FILE_UNIX_BASIC_INFO *info_buf_source = NULL;
1779 FILE_UNIX_BASIC_INFO *info_buf_target;
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +04001780 unsigned int xid;
1781 int rc, tmprc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001782
Miklos Szeredi7c33d592014-07-23 15:15:36 +02001783 if (flags & ~RENAME_NOREPLACE)
1784 return -EINVAL;
1785
Jeff Layton639e7a92010-09-03 11:50:09 -04001786 cifs_sb = CIFS_SB(source_dir->i_sb);
Jeff Layton7ffec372010-09-29 19:51:11 -04001787 tlink = cifs_sb_tlink(cifs_sb);
1788 if (IS_ERR(tlink))
1789 return PTR_ERR(tlink);
1790 tcon = tlink_tcon(tlink);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001791
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +04001792 xid = get_xid();
Steve Frenchee2fd962008-09-23 18:23:33 +00001793
1794 /*
Steve Frenchee2fd962008-09-23 18:23:33 +00001795 * we already have the rename sem so we do not need to
1796 * grab it again here to protect the path integrity
1797 */
Pavel Shilovsky8ceb9842012-09-18 16:20:30 -07001798 from_name = build_path_from_dentry(source_dentry);
1799 if (from_name == NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001800 rc = -ENOMEM;
1801 goto cifs_rename_exit;
1802 }
1803
Pavel Shilovsky8ceb9842012-09-18 16:20:30 -07001804 to_name = build_path_from_dentry(target_dentry);
1805 if (to_name == NULL) {
Steve Frenchee2fd962008-09-23 18:23:33 +00001806 rc = -ENOMEM;
1807 goto cifs_rename_exit;
1808 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001809
Pavel Shilovsky8ceb9842012-09-18 16:20:30 -07001810 rc = cifs_do_rename(xid, source_dentry, from_name, target_dentry,
1811 to_name);
Steve Frenchee2fd962008-09-23 18:23:33 +00001812
Miklos Szeredi7c33d592014-07-23 15:15:36 +02001813 /*
1814 * No-replace is the natural behavior for CIFS, so skip unlink hacks.
1815 */
1816 if (flags & RENAME_NOREPLACE)
1817 goto cifs_rename_exit;
1818
Jeff Layton14121bd2008-10-20 14:45:22 -04001819 if (rc == -EEXIST && tcon->unix_ext) {
Steve Frenchee2fd962008-09-23 18:23:33 +00001820 /*
Pavel Shilovsky8ceb9842012-09-18 16:20:30 -07001821 * Are src and dst hardlinks of same inode? We can only tell
1822 * with unix extensions enabled.
Steve Frenchee2fd962008-09-23 18:23:33 +00001823 */
Jeff Layton14121bd2008-10-20 14:45:22 -04001824 info_buf_source =
Kees Cook6da2ec52018-06-12 13:55:00 -07001825 kmalloc_array(2, sizeof(FILE_UNIX_BASIC_INFO),
Jeff Layton14121bd2008-10-20 14:45:22 -04001826 GFP_KERNEL);
1827 if (info_buf_source == NULL) {
1828 rc = -ENOMEM;
1829 goto cifs_rename_exit;
1830 }
1831
1832 info_buf_target = info_buf_source + 1;
Pavel Shilovsky8ceb9842012-09-18 16:20:30 -07001833 tmprc = CIFSSMBUnixQPathInfo(xid, tcon, from_name,
1834 info_buf_source,
1835 cifs_sb->local_nls,
Steve French2baa2682014-09-27 02:19:01 -05001836 cifs_remap(cifs_sb));
Jeff Layton8d281ef2008-10-22 13:57:01 -04001837 if (tmprc != 0)
Jeff Layton14121bd2008-10-20 14:45:22 -04001838 goto unlink_target;
1839
Pavel Shilovsky8ceb9842012-09-18 16:20:30 -07001840 tmprc = CIFSSMBUnixQPathInfo(xid, tcon, to_name,
1841 info_buf_target,
1842 cifs_sb->local_nls,
Steve French2baa2682014-09-27 02:19:01 -05001843 cifs_remap(cifs_sb));
Jeff Layton14121bd2008-10-20 14:45:22 -04001844
Jeff Layton8d281ef2008-10-22 13:57:01 -04001845 if (tmprc == 0 && (info_buf_source->UniqueId ==
Jeff Laytonae6884a2008-11-03 14:05:08 -05001846 info_buf_target->UniqueId)) {
Jeff Layton14121bd2008-10-20 14:45:22 -04001847 /* same file, POSIX says that this is a noop */
Jeff Laytonae6884a2008-11-03 14:05:08 -05001848 rc = 0;
Jeff Layton14121bd2008-10-20 14:45:22 -04001849 goto cifs_rename_exit;
Jeff Laytonae6884a2008-11-03 14:05:08 -05001850 }
Pavel Shilovsky8ceb9842012-09-18 16:20:30 -07001851 }
1852 /*
1853 * else ... BB we could add the same check for Windows by
1854 * checking the UniqueId via FILE_INTERNAL_INFO
1855 */
Jeff Layton14121bd2008-10-20 14:45:22 -04001856
Jeff Layton14121bd2008-10-20 14:45:22 -04001857unlink_target:
Jeff Laytonfc6f3942009-04-17 11:45:30 -04001858 /* Try unlinking the target dentry if it's not negative */
David Howells2b0143b2015-03-17 22:25:59 +00001859 if (d_really_is_positive(target_dentry) && (rc == -EACCES || rc == -EEXIST)) {
Pavel Shilovskya07d3222014-08-22 13:32:09 +04001860 if (d_is_dir(target_dentry))
1861 tmprc = cifs_rmdir(target_dir, target_dentry);
1862 else
1863 tmprc = cifs_unlink(target_dir, target_dentry);
Jeff Layton14121bd2008-10-20 14:45:22 -04001864 if (tmprc)
1865 goto cifs_rename_exit;
Pavel Shilovsky8ceb9842012-09-18 16:20:30 -07001866 rc = cifs_do_rename(xid, source_dentry, from_name,
1867 target_dentry, to_name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001868 }
1869
Pavel Shilovskyb46799a2014-08-18 20:49:58 +04001870 /* force revalidate to go get info when needed */
1871 CIFS_I(source_dir)->time = CIFS_I(target_dir)->time = 0;
1872
1873 source_dir->i_ctime = source_dir->i_mtime = target_dir->i_ctime =
Deepa Dinamanie37fea52017-05-08 15:59:16 -07001874 target_dir->i_mtime = current_time(source_dir);
Pavel Shilovskyb46799a2014-08-18 20:49:58 +04001875
Linus Torvalds1da177e2005-04-16 15:20:36 -07001876cifs_rename_exit:
Steve Frenchee2fd962008-09-23 18:23:33 +00001877 kfree(info_buf_source);
Pavel Shilovsky8ceb9842012-09-18 16:20:30 -07001878 kfree(from_name);
1879 kfree(to_name);
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +04001880 free_xid(xid);
Jeff Layton7ffec372010-09-29 19:51:11 -04001881 cifs_put_tlink(tlink);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001882 return rc;
1883}
1884
Jeff Laytondf2cf172010-02-12 07:44:16 -05001885static bool
1886cifs_inode_needs_reval(struct inode *inode)
1887{
1888 struct cifsInodeInfo *cifs_i = CIFS_I(inode);
Suresh Jayaraman6d20e842010-12-01 14:42:28 +05301889 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
Jeff Laytondf2cf172010-02-12 07:44:16 -05001890
Ronnie Sahlberg57c55cd2018-05-24 06:54:27 +10001891 if (cifs_i->time == 0)
1892 return true;
1893
Pavel Shilovsky18cceb62013-09-05 13:01:06 +04001894 if (CIFS_CACHE_READ(cifs_i))
Jeff Laytondf2cf172010-02-12 07:44:16 -05001895 return false;
1896
1897 if (!lookupCacheEnabled)
1898 return true;
1899
Jeff Laytona87c9ad2014-03-26 07:24:23 -07001900 if (!cifs_sb->actimeo)
1901 return true;
1902
Suresh Jayaraman6d20e842010-12-01 14:42:28 +05301903 if (!time_in_range(jiffies, cifs_i->time,
1904 cifs_i->time + cifs_sb->actimeo))
Jeff Laytondf2cf172010-02-12 07:44:16 -05001905 return true;
1906
Jeff Laytondb192722010-05-17 14:51:49 -04001907 /* hardlinked files w/ noserverino get "special" treatment */
Suresh Jayaraman6d20e842010-12-01 14:42:28 +05301908 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) &&
Jeff Laytondb192722010-05-17 14:51:49 -04001909 S_ISREG(inode->i_mode) && inode->i_nlink != 1)
1910 return true;
1911
Jeff Laytondf2cf172010-02-12 07:44:16 -05001912 return false;
1913}
1914
Suresh Jayaraman523fb8c2010-11-29 22:39:47 +05301915/*
1916 * Zap the cache. Called when invalid_mapping flag is set.
1917 */
Pavel Shilovsky6feb9892011-04-07 18:18:11 +04001918int
Jeff Laytondf2cf172010-02-12 07:44:16 -05001919cifs_invalidate_mapping(struct inode *inode)
1920{
Pavel Shilovsky6feb9892011-04-07 18:18:11 +04001921 int rc = 0;
Jeff Laytondf2cf172010-02-12 07:44:16 -05001922
Jeff Laytondf2cf172010-02-12 07:44:16 -05001923 if (inode->i_mapping && inode->i_mapping->nrpages != 0) {
Pavel Shilovsky257fb1f2011-03-16 01:55:32 +03001924 rc = invalidate_inode_pages2(inode->i_mapping);
Jeff Layton4f73c7d2014-04-30 09:31:47 -04001925 if (rc)
Joe Perchesf96637b2013-05-04 22:12:25 -05001926 cifs_dbg(VFS, "%s: could not invalidate inode %p\n",
1927 __func__, inode);
Jeff Laytondf2cf172010-02-12 07:44:16 -05001928 }
Pavel Shilovsky257fb1f2011-03-16 01:55:32 +03001929
Suresh Jayaraman9451a9a2010-07-05 18:12:45 +05301930 cifs_fscache_reset_inode_cookie(inode);
Pavel Shilovsky6feb9892011-04-07 18:18:11 +04001931 return rc;
Jeff Laytondf2cf172010-02-12 07:44:16 -05001932}
1933
Jeff Layton4f73c7d2014-04-30 09:31:47 -04001934/**
1935 * cifs_wait_bit_killable - helper for functions that are sleeping on bit locks
1936 * @word: long word containing the bit lock
1937 */
1938static int
Peter Zijlstradfd01f02015-12-13 22:11:16 +01001939cifs_wait_bit_killable(struct wait_bit_key *key, int mode)
Jeff Layton4f73c7d2014-04-30 09:31:47 -04001940{
Jeff Layton4f73c7d2014-04-30 09:31:47 -04001941 freezable_schedule_unsafe();
Peter Zijlstradfd01f02015-12-13 22:11:16 +01001942 if (signal_pending_state(mode, current))
1943 return -ERESTARTSYS;
Jeff Layton4f73c7d2014-04-30 09:31:47 -04001944 return 0;
1945}
1946
Jeff Laytone284e532014-04-30 09:31:46 -04001947int
1948cifs_revalidate_mapping(struct inode *inode)
1949{
Jeff Layton4f73c7d2014-04-30 09:31:47 -04001950 int rc;
1951 unsigned long *flags = &CIFS_I(inode)->flags;
1952
NeilBrown74316202014-07-07 15:16:04 +10001953 rc = wait_on_bit_lock_action(flags, CIFS_INO_LOCK, cifs_wait_bit_killable,
1954 TASK_KILLABLE);
Jeff Layton4f73c7d2014-04-30 09:31:47 -04001955 if (rc)
1956 return rc;
1957
1958 if (test_and_clear_bit(CIFS_INO_INVALID_MAPPING, flags)) {
1959 rc = cifs_invalidate_mapping(inode);
1960 if (rc)
1961 set_bit(CIFS_INO_INVALID_MAPPING, flags);
1962 }
1963
1964 clear_bit_unlock(CIFS_INO_LOCK, flags);
Linus Torvaldsb1cce802014-06-09 19:08:43 -07001965 smp_mb__after_atomic();
Jeff Layton4f73c7d2014-04-30 09:31:47 -04001966 wake_up_bit(flags, CIFS_INO_LOCK);
1967
1968 return rc;
1969}
1970
1971int
1972cifs_zap_mapping(struct inode *inode)
1973{
1974 set_bit(CIFS_INO_INVALID_MAPPING, &CIFS_I(inode)->flags);
1975 return cifs_revalidate_mapping(inode);
Jeff Laytone284e532014-04-30 09:31:46 -04001976}
1977
Pavel Shilovsky6feb9892011-04-07 18:18:11 +04001978int cifs_revalidate_file_attr(struct file *filp)
Jeff Laytonabab0952010-02-12 07:44:18 -05001979{
1980 int rc = 0;
Al Viro496ad9a2013-01-23 17:07:38 -05001981 struct inode *inode = file_inode(filp);
Jeff Laytonba00ba642010-09-20 16:01:31 -07001982 struct cifsFileInfo *cfile = (struct cifsFileInfo *) filp->private_data;
Jeff Laytonabab0952010-02-12 07:44:18 -05001983
1984 if (!cifs_inode_needs_reval(inode))
Pavel Shilovsky6feb9892011-04-07 18:18:11 +04001985 return rc;
Jeff Laytonabab0952010-02-12 07:44:18 -05001986
Jeff Layton13cfb732010-09-29 19:51:11 -04001987 if (tlink_tcon(cfile->tlink)->unix_ext)
Jeff Laytonabab0952010-02-12 07:44:18 -05001988 rc = cifs_get_file_info_unix(filp);
1989 else
1990 rc = cifs_get_file_info(filp);
1991
Jeff Laytonabab0952010-02-12 07:44:18 -05001992 return rc;
1993}
1994
Pavel Shilovsky6feb9892011-04-07 18:18:11 +04001995int cifs_revalidate_dentry_attr(struct dentry *dentry)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001996{
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +04001997 unsigned int xid;
Jeff Laytondf2cf172010-02-12 07:44:16 -05001998 int rc = 0;
David Howells2b0143b2015-03-17 22:25:59 +00001999 struct inode *inode = d_inode(dentry);
Jeff Laytondf2cf172010-02-12 07:44:16 -05002000 struct super_block *sb = dentry->d_sb;
Pavel Shilovsky6feb9892011-04-07 18:18:11 +04002001 char *full_path = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002002
Jeff Laytondf2cf172010-02-12 07:44:16 -05002003 if (inode == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002004 return -ENOENT;
2005
Jeff Laytondf2cf172010-02-12 07:44:16 -05002006 if (!cifs_inode_needs_reval(inode))
Pavel Shilovsky6feb9892011-04-07 18:18:11 +04002007 return rc;
2008
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +04002009 xid = get_xid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002010
2011 /* can not safely grab the rename sem here if rename calls revalidate
2012 since that would deadlock */
Jeff Laytondf2cf172010-02-12 07:44:16 -05002013 full_path = build_path_from_dentry(dentry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002014 if (full_path == NULL) {
Suresh Jayaraman0f3bc092009-06-25 18:12:34 +05302015 rc = -ENOMEM;
Pavel Shilovsky6feb9892011-04-07 18:18:11 +04002016 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002017 }
Jeff Laytondf2cf172010-02-12 07:44:16 -05002018
Joe Perchesf96637b2013-05-04 22:12:25 -05002019 cifs_dbg(FYI, "Update attributes: %s inode 0x%p count %d dentry: 0x%p d_time %ld jiffies %ld\n",
2020 full_path, inode, inode->i_count.counter,
Miklos Szeredia00be0e2016-09-16 12:44:21 +02002021 dentry, cifs_get_time(dentry), jiffies);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002022
Jeff Layton0d424ad2010-09-20 16:01:35 -07002023 if (cifs_sb_master_tcon(CIFS_SB(sb))->unix_ext)
Jeff Laytondf2cf172010-02-12 07:44:16 -05002024 rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
2025 else
2026 rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
2027 xid, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002028
Pavel Shilovsky6feb9892011-04-07 18:18:11 +04002029out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002030 kfree(full_path);
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +04002031 free_xid(xid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002032 return rc;
2033}
2034
Pavel Shilovsky6feb9892011-04-07 18:18:11 +04002035int cifs_revalidate_file(struct file *filp)
2036{
2037 int rc;
Al Viro496ad9a2013-01-23 17:07:38 -05002038 struct inode *inode = file_inode(filp);
Pavel Shilovsky6feb9892011-04-07 18:18:11 +04002039
2040 rc = cifs_revalidate_file_attr(filp);
2041 if (rc)
2042 return rc;
2043
Jeff Laytone284e532014-04-30 09:31:46 -04002044 return cifs_revalidate_mapping(inode);
Pavel Shilovsky6feb9892011-04-07 18:18:11 +04002045}
2046
2047/* revalidate a dentry's inode attributes */
2048int cifs_revalidate_dentry(struct dentry *dentry)
2049{
2050 int rc;
David Howells2b0143b2015-03-17 22:25:59 +00002051 struct inode *inode = d_inode(dentry);
Pavel Shilovsky6feb9892011-04-07 18:18:11 +04002052
2053 rc = cifs_revalidate_dentry_attr(dentry);
2054 if (rc)
2055 return rc;
2056
Jeff Laytone284e532014-04-30 09:31:46 -04002057 return cifs_revalidate_mapping(inode);
Pavel Shilovsky6feb9892011-04-07 18:18:11 +04002058}
2059
David Howellsa528d352017-01-31 16:46:22 +00002060int cifs_getattr(const struct path *path, struct kstat *stat,
2061 u32 request_mask, unsigned int flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002062{
David Howellsa528d352017-01-31 16:46:22 +00002063 struct dentry *dentry = path->dentry;
Jeff Layton3aa1c8c2010-10-07 14:46:28 -04002064 struct cifs_sb_info *cifs_sb = CIFS_SB(dentry->d_sb);
Steve French96daf2b2011-05-27 04:34:02 +00002065 struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
David Howells2b0143b2015-03-17 22:25:59 +00002066 struct inode *inode = d_inode(dentry);
Pavel Shilovsky6feb9892011-04-07 18:18:11 +04002067 int rc;
Jeff Layton3aa1c8c2010-10-07 14:46:28 -04002068
Pavel Shilovsky6feb9892011-04-07 18:18:11 +04002069 /*
2070 * We need to be sure that all dirty pages are written and the server
2071 * has actual ctime, mtime and file length.
2072 */
Pavel Shilovsky18cceb62013-09-05 13:01:06 +04002073 if (!CIFS_CACHE_READ(CIFS_I(inode)) && inode->i_mapping &&
Pavel Shilovsky6feb9892011-04-07 18:18:11 +04002074 inode->i_mapping->nrpages != 0) {
2075 rc = filemap_fdatawait(inode->i_mapping);
Steve French156ecb22011-05-20 17:00:01 +00002076 if (rc) {
2077 mapping_set_error(inode->i_mapping, rc);
2078 return rc;
2079 }
Steve French5fe14c82006-11-07 19:26:33 +00002080 }
Pavel Shilovsky6feb9892011-04-07 18:18:11 +04002081
2082 rc = cifs_revalidate_dentry_attr(dentry);
2083 if (rc)
2084 return rc;
2085
2086 generic_fillattr(inode, stat);
2087 stat->blksize = CIFS_MAX_MSGSIZE;
2088 stat->ino = CIFS_I(inode)->uniqueid;
2089
Steve French6e70e262017-09-21 21:32:29 -05002090 /* old CIFS Unix Extensions doesn't return create time */
2091 if (CIFS_I(inode)->createtime) {
2092 stat->result_mask |= STATX_BTIME;
Arnd Bergmann95390202018-06-19 17:27:58 +02002093 stat->btime =
2094 cifs_NTtimeToUnix(cpu_to_le64(CIFS_I(inode)->createtime));
Steve French6e70e262017-09-21 21:32:29 -05002095 }
2096
2097 stat->attributes_mask |= (STATX_ATTR_COMPRESSED | STATX_ATTR_ENCRYPTED);
2098 if (CIFS_I(inode)->cifsAttrs & FILE_ATTRIBUTE_COMPRESSED)
2099 stat->attributes |= STATX_ATTR_COMPRESSED;
2100 if (CIFS_I(inode)->cifsAttrs & FILE_ATTRIBUTE_ENCRYPTED)
2101 stat->attributes |= STATX_ATTR_ENCRYPTED;
2102
Pavel Shilovsky6feb9892011-04-07 18:18:11 +04002103 /*
Jeff Laytond3d1fce2012-11-25 08:00:40 -05002104 * If on a multiuser mount without unix extensions or cifsacl being
2105 * enabled, and the admin hasn't overridden them, set the ownership
2106 * to the fsuid/fsgid of the current process.
Pavel Shilovsky6feb9892011-04-07 18:18:11 +04002107 */
2108 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER) &&
Jeff Laytond3d1fce2012-11-25 08:00:40 -05002109 !(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) &&
Pavel Shilovsky6feb9892011-04-07 18:18:11 +04002110 !tcon->unix_ext) {
2111 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID))
2112 stat->uid = current_fsuid();
2113 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID))
2114 stat->gid = current_fsgid();
2115 }
2116 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002117}
2118
2119static int cifs_truncate_page(struct address_space *mapping, loff_t from)
2120{
Kirill A. Shutemov09cbfea2016-04-01 15:29:47 +03002121 pgoff_t index = from >> PAGE_SHIFT;
2122 unsigned offset = from & (PAGE_SIZE - 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002123 struct page *page;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002124 int rc = 0;
2125
2126 page = grab_cache_page(mapping, index);
2127 if (!page)
2128 return -ENOMEM;
2129
Kirill A. Shutemov09cbfea2016-04-01 15:29:47 +03002130 zero_user_segment(page, offset, PAGE_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002131 unlock_page(page);
Kirill A. Shutemov09cbfea2016-04-01 15:29:47 +03002132 put_page(page);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002133 return rc;
2134}
2135
Christoph Hellwig1b947462010-07-18 17:51:21 -04002136static void cifs_setsize(struct inode *inode, loff_t offset)
Steve French3677db12007-02-26 16:46:11 +00002137{
Ronnie Sahlberg57c55cd2018-05-24 06:54:27 +10002138 struct cifsInodeInfo *cifs_i = CIFS_I(inode);
2139
Steve Frenchba6a46a2007-02-26 20:06:29 +00002140 spin_lock(&inode->i_lock);
Steve French3677db12007-02-26 16:46:11 +00002141 i_size_write(inode, offset);
Steve Frenchba6a46a2007-02-26 20:06:29 +00002142 spin_unlock(&inode->i_lock);
Christoph Hellwig1b947462010-07-18 17:51:21 -04002143
Ronnie Sahlberg57c55cd2018-05-24 06:54:27 +10002144 /* Cached inode must be refreshed on truncate */
2145 cifs_i->time = 0;
Kirill A. Shutemov7caef262013-09-12 15:13:56 -07002146 truncate_pagecache(inode, offset);
Steve French3677db12007-02-26 16:46:11 +00002147}
2148
Jeff Layton8efdbde2008-07-23 21:28:12 +00002149static int
2150cifs_set_file_size(struct inode *inode, struct iattr *attrs,
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +04002151 unsigned int xid, char *full_path)
Jeff Layton8efdbde2008-07-23 21:28:12 +00002152{
2153 int rc;
2154 struct cifsFileInfo *open_file;
2155 struct cifsInodeInfo *cifsInode = CIFS_I(inode);
2156 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
Jeff Layton7ffec372010-09-29 19:51:11 -04002157 struct tcon_link *tlink = NULL;
Pavel Shilovskyd1433412012-09-18 16:20:31 -07002158 struct cifs_tcon *tcon = NULL;
2159 struct TCP_Server_Info *server;
Jeff Layton8efdbde2008-07-23 21:28:12 +00002160
2161 /*
2162 * To avoid spurious oplock breaks from server, in the case of
2163 * inodes that we already have open, avoid doing path based
2164 * setting of file size if we can do it by handle.
2165 * This keeps our caching token (oplock) and avoids timeouts
2166 * when the local oplock break takes longer to flush
2167 * writebehind data than the SMB timeout for the SetPathInfo
2168 * request would allow
2169 */
Jeff Layton6508d902010-09-29 19:51:11 -04002170 open_file = find_writable_file(cifsInode, true);
Jeff Layton8efdbde2008-07-23 21:28:12 +00002171 if (open_file) {
Pavel Shilovskyd1433412012-09-18 16:20:31 -07002172 tcon = tlink_tcon(open_file->tlink);
2173 server = tcon->ses->server;
2174 if (server->ops->set_file_size)
2175 rc = server->ops->set_file_size(xid, tcon, open_file,
2176 attrs->ia_size, false);
2177 else
2178 rc = -ENOSYS;
Dave Kleikamp6ab409b2009-08-31 11:07:12 -04002179 cifsFileInfo_put(open_file);
Joe Perchesf96637b2013-05-04 22:12:25 -05002180 cifs_dbg(FYI, "SetFSize for attrs rc = %d\n", rc);
Jeff Layton8efdbde2008-07-23 21:28:12 +00002181 } else
2182 rc = -EINVAL;
2183
Pavel Shilovskyd1433412012-09-18 16:20:31 -07002184 if (!rc)
2185 goto set_size_out;
Jeff Laytonba00ba642010-09-20 16:01:31 -07002186
Pavel Shilovskyd1433412012-09-18 16:20:31 -07002187 if (tcon == NULL) {
2188 tlink = cifs_sb_tlink(cifs_sb);
2189 if (IS_ERR(tlink))
2190 return PTR_ERR(tlink);
2191 tcon = tlink_tcon(tlink);
2192 server = tcon->ses->server;
Jeff Layton8efdbde2008-07-23 21:28:12 +00002193 }
2194
Pavel Shilovskyd1433412012-09-18 16:20:31 -07002195 /*
2196 * Set file size by pathname rather than by handle either because no
2197 * valid, writeable file handle for it was found or because there was
2198 * an error setting it by handle.
2199 */
2200 if (server->ops->set_path_size)
2201 rc = server->ops->set_path_size(xid, tcon, full_path,
2202 attrs->ia_size, cifs_sb, false);
2203 else
2204 rc = -ENOSYS;
Joe Perchesf96637b2013-05-04 22:12:25 -05002205 cifs_dbg(FYI, "SetEOF by path (setattrs) rc = %d\n", rc);
Pavel Shilovskyd1433412012-09-18 16:20:31 -07002206
Pavel Shilovskyd1433412012-09-18 16:20:31 -07002207 if (tlink)
2208 cifs_put_tlink(tlink);
2209
2210set_size_out:
Jeff Layton8efdbde2008-07-23 21:28:12 +00002211 if (rc == 0) {
Jeff Laytonfbec9ab2009-04-03 13:44:00 -04002212 cifsInode->server_eof = attrs->ia_size;
Christoph Hellwig1b947462010-07-18 17:51:21 -04002213 cifs_setsize(inode, attrs->ia_size);
Jeff Layton8efdbde2008-07-23 21:28:12 +00002214 cifs_truncate_page(inode->i_mapping, inode->i_size);
2215 }
2216
2217 return rc;
2218}
2219
Jeff Layton3fe5c1d2008-08-02 07:26:12 -04002220static int
2221cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
2222{
2223 int rc;
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +04002224 unsigned int xid;
Jeff Layton3fe5c1d2008-08-02 07:26:12 -04002225 char *full_path = NULL;
David Howells2b0143b2015-03-17 22:25:59 +00002226 struct inode *inode = d_inode(direntry);
Jeff Layton3fe5c1d2008-08-02 07:26:12 -04002227 struct cifsInodeInfo *cifsInode = CIFS_I(inode);
2228 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
Jeff Layton7ffec372010-09-29 19:51:11 -04002229 struct tcon_link *tlink;
Steve French96daf2b2011-05-27 04:34:02 +00002230 struct cifs_tcon *pTcon;
Jeff Layton3fe5c1d2008-08-02 07:26:12 -04002231 struct cifs_unix_set_info_args *args = NULL;
Jeff Layton3bbeeb32009-07-09 20:02:50 -04002232 struct cifsFileInfo *open_file;
Jeff Layton3fe5c1d2008-08-02 07:26:12 -04002233
Al Viro35c265e2014-08-19 20:25:34 -04002234 cifs_dbg(FYI, "setattr_unix on file %pd attrs->ia_valid=0x%x\n",
2235 direntry, attrs->ia_valid);
Jeff Layton3fe5c1d2008-08-02 07:26:12 -04002236
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +04002237 xid = get_xid();
Jeff Layton3fe5c1d2008-08-02 07:26:12 -04002238
Christoph Hellwigdb78b872010-06-04 11:30:03 +02002239 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
2240 attrs->ia_valid |= ATTR_FORCE;
2241
Jan Kara31051c82016-05-26 16:55:18 +02002242 rc = setattr_prepare(direntry, attrs);
Christoph Hellwigdb78b872010-06-04 11:30:03 +02002243 if (rc < 0)
2244 goto out;
Jeff Layton3fe5c1d2008-08-02 07:26:12 -04002245
2246 full_path = build_path_from_dentry(direntry);
2247 if (full_path == NULL) {
2248 rc = -ENOMEM;
2249 goto out;
2250 }
2251
Jeff Layton0f4d6342009-03-26 13:35:37 -04002252 /*
2253 * Attempt to flush data before changing attributes. We need to do
2254 * this for ATTR_SIZE and ATTR_MTIME for sure, and if we change the
2255 * ownership or mode then we may also need to do this. Here, we take
2256 * the safe way out and just do the flush on all setattr requests. If
2257 * the flush returns error, store it to report later and continue.
2258 *
2259 * BB: This should be smarter. Why bother flushing pages that
2260 * will be truncated anyway? Also, should we error out here if
2261 * the flush returns error?
2262 */
2263 rc = filemap_write_and_wait(inode->i_mapping);
Jeff Laytoneb4b7562010-10-22 14:52:29 -04002264 mapping_set_error(inode->i_mapping, rc);
2265 rc = 0;
Jeff Layton3fe5c1d2008-08-02 07:26:12 -04002266
2267 if (attrs->ia_valid & ATTR_SIZE) {
2268 rc = cifs_set_file_size(inode, attrs, xid, full_path);
2269 if (rc != 0)
2270 goto out;
2271 }
2272
2273 /* skip mode change if it's just for clearing setuid/setgid */
2274 if (attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))
2275 attrs->ia_valid &= ~ATTR_MODE;
2276
2277 args = kmalloc(sizeof(*args), GFP_KERNEL);
2278 if (args == NULL) {
2279 rc = -ENOMEM;
2280 goto out;
2281 }
2282
2283 /* set up the struct */
2284 if (attrs->ia_valid & ATTR_MODE)
2285 args->mode = attrs->ia_mode;
2286 else
2287 args->mode = NO_CHANGE_64;
2288
2289 if (attrs->ia_valid & ATTR_UID)
2290 args->uid = attrs->ia_uid;
2291 else
Eric W. Biederman49418b22013-02-06 00:57:56 -08002292 args->uid = INVALID_UID; /* no change */
Jeff Layton3fe5c1d2008-08-02 07:26:12 -04002293
2294 if (attrs->ia_valid & ATTR_GID)
2295 args->gid = attrs->ia_gid;
2296 else
Eric W. Biederman49418b22013-02-06 00:57:56 -08002297 args->gid = INVALID_GID; /* no change */
Jeff Layton3fe5c1d2008-08-02 07:26:12 -04002298
2299 if (attrs->ia_valid & ATTR_ATIME)
Arnd Bergmann95390202018-06-19 17:27:58 +02002300 args->atime = cifs_UnixTimeToNT(attrs->ia_atime);
Jeff Layton3fe5c1d2008-08-02 07:26:12 -04002301 else
2302 args->atime = NO_CHANGE_64;
2303
2304 if (attrs->ia_valid & ATTR_MTIME)
Arnd Bergmann95390202018-06-19 17:27:58 +02002305 args->mtime = cifs_UnixTimeToNT(attrs->ia_mtime);
Jeff Layton3fe5c1d2008-08-02 07:26:12 -04002306 else
2307 args->mtime = NO_CHANGE_64;
2308
2309 if (attrs->ia_valid & ATTR_CTIME)
Arnd Bergmann95390202018-06-19 17:27:58 +02002310 args->ctime = cifs_UnixTimeToNT(attrs->ia_ctime);
Jeff Layton3fe5c1d2008-08-02 07:26:12 -04002311 else
2312 args->ctime = NO_CHANGE_64;
2313
2314 args->device = 0;
Jeff Layton6508d902010-09-29 19:51:11 -04002315 open_file = find_writable_file(cifsInode, true);
Jeff Layton3bbeeb32009-07-09 20:02:50 -04002316 if (open_file) {
Pavel Shilovsky4b4de762012-09-18 16:20:26 -07002317 u16 nfid = open_file->fid.netfid;
Jeff Layton3bbeeb32009-07-09 20:02:50 -04002318 u32 npid = open_file->pid;
Jeff Layton13cfb732010-09-29 19:51:11 -04002319 pTcon = tlink_tcon(open_file->tlink);
Jeff Layton3bbeeb32009-07-09 20:02:50 -04002320 rc = CIFSSMBUnixSetFileInfo(xid, pTcon, args, nfid, npid);
Dave Kleikamp6ab409b2009-08-31 11:07:12 -04002321 cifsFileInfo_put(open_file);
Jeff Layton3bbeeb32009-07-09 20:02:50 -04002322 } else {
Jeff Layton7ffec372010-09-29 19:51:11 -04002323 tlink = cifs_sb_tlink(cifs_sb);
2324 if (IS_ERR(tlink)) {
2325 rc = PTR_ERR(tlink);
2326 goto out;
2327 }
2328 pTcon = tlink_tcon(tlink);
Jeff Layton3bbeeb32009-07-09 20:02:50 -04002329 rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, args,
Jeff Layton01ea95e2009-07-09 20:02:49 -04002330 cifs_sb->local_nls,
Nakajima Akirabc8ebdc42015-02-13 15:35:58 +09002331 cifs_remap(cifs_sb));
Jeff Layton7ffec372010-09-29 19:51:11 -04002332 cifs_put_tlink(tlink);
Jeff Layton3bbeeb32009-07-09 20:02:50 -04002333 }
Jeff Layton3fe5c1d2008-08-02 07:26:12 -04002334
Christoph Hellwig10257742010-06-04 11:30:02 +02002335 if (rc)
2336 goto out;
Steve Frenchccd4bb12010-02-08 17:39:58 +00002337
Christoph Hellwig10257742010-06-04 11:30:02 +02002338 if ((attrs->ia_valid & ATTR_SIZE) &&
Christoph Hellwig1b947462010-07-18 17:51:21 -04002339 attrs->ia_size != i_size_read(inode))
2340 truncate_setsize(inode, attrs->ia_size);
Christoph Hellwig10257742010-06-04 11:30:02 +02002341
2342 setattr_copy(inode, attrs);
2343 mark_inode_dirty(inode);
2344
2345 /* force revalidate when any of these times are set since some
2346 of the fs types (eg ext3, fat) do not have fine enough
2347 time granularity to match protocol, and we do not have a
2348 a way (yet) to query the server fs's time granularity (and
2349 whether it rounds times down).
2350 */
2351 if (attrs->ia_valid & (ATTR_MTIME | ATTR_CTIME))
2352 cifsInode->time = 0;
Jeff Layton3fe5c1d2008-08-02 07:26:12 -04002353out:
2354 kfree(args);
2355 kfree(full_path);
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +04002356 free_xid(xid);
Jeff Layton3fe5c1d2008-08-02 07:26:12 -04002357 return rc;
2358}
2359
Jeff Layton0510eeb2008-08-02 07:26:12 -04002360static int
2361cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002362{
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +04002363 unsigned int xid;
Eric W. Biederman8abf2772013-02-06 00:33:17 -08002364 kuid_t uid = INVALID_UID;
2365 kgid_t gid = INVALID_GID;
David Howells2b0143b2015-03-17 22:25:59 +00002366 struct inode *inode = d_inode(direntry);
Jeff Layton3fe5c1d2008-08-02 07:26:12 -04002367 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
Jeff Layton3fe5c1d2008-08-02 07:26:12 -04002368 struct cifsInodeInfo *cifsInode = CIFS_I(inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002369 char *full_path = NULL;
2370 int rc = -EACCES;
Jeff Laytonfeb3e202008-08-02 07:26:12 -04002371 __u32 dosattr = 0;
Jeff Layton4e1e7fb2008-08-02 07:26:12 -04002372 __u64 mode = NO_CHANGE_64;
Jeff Layton3fe5c1d2008-08-02 07:26:12 -04002373
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +04002374 xid = get_xid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002375
Al Viro35c265e2014-08-19 20:25:34 -04002376 cifs_dbg(FYI, "setattr on file %pd attrs->iavalid 0x%x\n",
2377 direntry, attrs->ia_valid);
Steve French6473a552005-11-29 20:20:10 -08002378
Christoph Hellwigdb78b872010-06-04 11:30:03 +02002379 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
2380 attrs->ia_valid |= ATTR_FORCE;
2381
Jan Kara31051c82016-05-26 16:55:18 +02002382 rc = setattr_prepare(direntry, attrs);
Christoph Hellwigdb78b872010-06-04 11:30:03 +02002383 if (rc < 0) {
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +04002384 free_xid(xid);
Christoph Hellwigdb78b872010-06-04 11:30:03 +02002385 return rc;
Steve French6473a552005-11-29 20:20:10 -08002386 }
Steve French50c2f752007-07-13 00:33:32 +00002387
Steve French7f573562005-08-30 11:32:14 -07002388 full_path = build_path_from_dentry(direntry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002389 if (full_path == NULL) {
Suresh Jayaraman0f3bc092009-06-25 18:12:34 +05302390 rc = -ENOMEM;
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +04002391 free_xid(xid);
Suresh Jayaraman0f3bc092009-06-25 18:12:34 +05302392 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002393 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002394
Jeff Layton0f4d6342009-03-26 13:35:37 -04002395 /*
2396 * Attempt to flush data before changing attributes. We need to do
2397 * this for ATTR_SIZE and ATTR_MTIME for sure, and if we change the
2398 * ownership or mode then we may also need to do this. Here, we take
2399 * the safe way out and just do the flush on all setattr requests. If
2400 * the flush returns error, store it to report later and continue.
2401 *
2402 * BB: This should be smarter. Why bother flushing pages that
2403 * will be truncated anyway? Also, should we error out here if
2404 * the flush returns error?
2405 */
2406 rc = filemap_write_and_wait(inode->i_mapping);
Jeff Laytoneb4b7562010-10-22 14:52:29 -04002407 mapping_set_error(inode->i_mapping, rc);
2408 rc = 0;
Jeff Laytoncea21802007-11-20 23:19:03 +00002409
Steve French50531442008-03-14 19:21:31 +00002410 if (attrs->ia_valid & ATTR_SIZE) {
Jeff Layton8efdbde2008-07-23 21:28:12 +00002411 rc = cifs_set_file_size(inode, attrs, xid, full_path);
2412 if (rc != 0)
Steve Frenche30dcf32005-09-20 20:49:16 -07002413 goto cifs_setattr_exit;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002414 }
Jeff Layton4ca691a2008-05-22 09:33:34 -04002415
Shirish Pargaonkara5ff3762011-10-13 10:26:03 -05002416 if (attrs->ia_valid & ATTR_UID)
2417 uid = attrs->ia_uid;
2418
2419 if (attrs->ia_valid & ATTR_GID)
2420 gid = attrs->ia_gid;
2421
2422#ifdef CONFIG_CIFS_ACL
2423 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
Eric W. Biederman8abf2772013-02-06 00:33:17 -08002424 if (uid_valid(uid) || gid_valid(gid)) {
Shirish Pargaonkara5ff3762011-10-13 10:26:03 -05002425 rc = id_mode_to_cifs_acl(inode, full_path, NO_CHANGE_64,
2426 uid, gid);
2427 if (rc) {
Joe Perchesf96637b2013-05-04 22:12:25 -05002428 cifs_dbg(FYI, "%s: Setting id failed with error: %d\n",
2429 __func__, rc);
Shirish Pargaonkara5ff3762011-10-13 10:26:03 -05002430 goto cifs_setattr_exit;
2431 }
2432 }
2433 } else
2434#endif /* CONFIG_CIFS_ACL */
Jeff Layton3fe5c1d2008-08-02 07:26:12 -04002435 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID))
Jeff Layton4ca691a2008-05-22 09:33:34 -04002436 attrs->ia_valid &= ~(ATTR_UID | ATTR_GID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002437
Jeff Laytond32c4f22007-10-18 03:05:22 -07002438 /* skip mode change if it's just for clearing setuid/setgid */
2439 if (attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))
2440 attrs->ia_valid &= ~ATTR_MODE;
2441
Linus Torvalds1da177e2005-04-16 15:20:36 -07002442 if (attrs->ia_valid & ATTR_MODE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002443 mode = attrs->ia_mode;
Steve Frenchcdbce9c82005-11-19 21:04:52 -08002444 rc = 0;
Jeff Layton79df1ba2010-12-06 12:52:08 -05002445#ifdef CONFIG_CIFS_ACL
Shirish Pargaonkar78415d22010-11-27 11:37:26 -06002446 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
Shirish Pargaonkara5ff3762011-10-13 10:26:03 -05002447 rc = id_mode_to_cifs_acl(inode, full_path, mode,
Eric W. Biederman8abf2772013-02-06 00:33:17 -08002448 INVALID_UID, INVALID_GID);
Shirish Pargaonkar78415d22010-11-27 11:37:26 -06002449 if (rc) {
Joe Perchesf96637b2013-05-04 22:12:25 -05002450 cifs_dbg(FYI, "%s: Setting ACL failed with error: %d\n",
2451 __func__, rc);
Shirish Pargaonkar78415d22010-11-27 11:37:26 -06002452 goto cifs_setattr_exit;
2453 }
2454 } else
Jeff Layton79df1ba2010-12-06 12:52:08 -05002455#endif /* CONFIG_CIFS_ACL */
Jeff Layton51328612008-05-22 09:33:34 -04002456 if (((mode & S_IWUGO) == 0) &&
2457 (cifsInode->cifsAttrs & ATTR_READONLY) == 0) {
Jeff Laytonfeb3e202008-08-02 07:26:12 -04002458
2459 dosattr = cifsInode->cifsAttrs | ATTR_READONLY;
2460
Jeff Layton51328612008-05-22 09:33:34 -04002461 /* fix up mode if we're not using dynperm */
2462 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) == 0)
2463 attrs->ia_mode = inode->i_mode & ~S_IWUGO;
2464 } else if ((mode & S_IWUGO) &&
2465 (cifsInode->cifsAttrs & ATTR_READONLY)) {
Jeff Laytonfeb3e202008-08-02 07:26:12 -04002466
2467 dosattr = cifsInode->cifsAttrs & ~ATTR_READONLY;
2468 /* Attributes of 0 are ignored */
2469 if (dosattr == 0)
2470 dosattr |= ATTR_NORMAL;
Jeff Layton51328612008-05-22 09:33:34 -04002471
2472 /* reset local inode permissions to normal */
2473 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) {
2474 attrs->ia_mode &= ~(S_IALLUGO);
2475 if (S_ISDIR(inode->i_mode))
2476 attrs->ia_mode |=
2477 cifs_sb->mnt_dir_mode;
2478 else
2479 attrs->ia_mode |=
2480 cifs_sb->mnt_file_mode;
2481 }
2482 } else if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) {
2483 /* ignore mode change - ATTR_READONLY hasn't changed */
2484 attrs->ia_valid &= ~ATTR_MODE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002485 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002486 }
2487
Jeff Laytonfeb3e202008-08-02 07:26:12 -04002488 if (attrs->ia_valid & (ATTR_MTIME|ATTR_ATIME|ATTR_CTIME) ||
2489 ((attrs->ia_valid & ATTR_MODE) && dosattr)) {
2490 rc = cifs_set_file_info(inode, attrs, xid, full_path, dosattr);
2491 /* BB: check for rc = -EOPNOTSUPP and switch to legacy mode */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002492
Steve Frenche30dcf32005-09-20 20:49:16 -07002493 /* Even if error on time set, no sense failing the call if
2494 the server would set the time to a reasonable value anyway,
2495 and this check ensures that we are not being called from
2496 sys_utimes in which case we ought to fail the call back to
2497 the user when the server rejects the call */
Steve Frenchfb8c4b12007-07-10 01:16:18 +00002498 if ((rc) && (attrs->ia_valid &
Jeff Laytonfeb3e202008-08-02 07:26:12 -04002499 (ATTR_MODE | ATTR_GID | ATTR_UID | ATTR_SIZE)))
Steve Frenche30dcf32005-09-20 20:49:16 -07002500 rc = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002501 }
2502
2503 /* do not need local check to inode_check_ok since the server does
2504 that */
Christoph Hellwig10257742010-06-04 11:30:02 +02002505 if (rc)
2506 goto cifs_setattr_exit;
2507
2508 if ((attrs->ia_valid & ATTR_SIZE) &&
Christoph Hellwig1b947462010-07-18 17:51:21 -04002509 attrs->ia_size != i_size_read(inode))
2510 truncate_setsize(inode, attrs->ia_size);
Christoph Hellwig10257742010-06-04 11:30:02 +02002511
2512 setattr_copy(inode, attrs);
2513 mark_inode_dirty(inode);
Christoph Hellwig10257742010-06-04 11:30:02 +02002514
Steve Frenche30dcf32005-09-20 20:49:16 -07002515cifs_setattr_exit:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002516 kfree(full_path);
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +04002517 free_xid(xid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002518 return rc;
2519}
2520
Jeff Layton0510eeb2008-08-02 07:26:12 -04002521int
2522cifs_setattr(struct dentry *direntry, struct iattr *attrs)
2523{
Al Virofc640052016-04-10 01:33:30 -04002524 struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb);
Steve French96daf2b2011-05-27 04:34:02 +00002525 struct cifs_tcon *pTcon = cifs_sb_master_tcon(cifs_sb);
Jeff Layton0510eeb2008-08-02 07:26:12 -04002526
2527 if (pTcon->unix_ext)
2528 return cifs_setattr_unix(direntry, attrs);
2529
2530 return cifs_setattr_nounix(direntry, attrs);
2531
2532 /* BB: add cifs_setattr_legacy for really old servers */
2533}
2534
Steve French99ee4db2007-02-27 05:35:17 +00002535#if 0
Linus Torvalds1da177e2005-04-16 15:20:36 -07002536void cifs_delete_inode(struct inode *inode)
2537{
Joe Perchesf96637b2013-05-04 22:12:25 -05002538 cifs_dbg(FYI, "In cifs_delete_inode, inode = 0x%p\n", inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002539 /* may have to add back in if and when safe distributed caching of
2540 directories added e.g. via FindNotify */
2541}
Steve French99ee4db2007-02-27 05:35:17 +00002542#endif