Blame view
fs/cifs/inode.c
78.4 KB
929be906f cifs: use SPDX-Li... |
1 |
// SPDX-License-Identifier: LGPL-2.1 |
1da177e4c Linux-2.6.12-rc2 |
2 |
/* |
1da177e4c Linux-2.6.12-rc2 |
3 |
* |
f19159dc5 [CIFS] Cleanup va... |
4 |
* Copyright (C) International Business Machines Corp., 2002,2010 |
1da177e4c Linux-2.6.12-rc2 |
5 6 |
* Author(s): Steve French (sfrench@us.ibm.com) * |
1da177e4c Linux-2.6.12-rc2 |
7 8 |
*/ #include <linux/fs.h> |
1da177e4c Linux-2.6.12-rc2 |
9 |
#include <linux/stat.h> |
5a0e3ad6a include cleanup: ... |
10 |
#include <linux/slab.h> |
1da177e4c Linux-2.6.12-rc2 |
11 |
#include <linux/pagemap.h> |
4f73c7d34 cifs: fix potenti... |
12 |
#include <linux/freezer.h> |
174cd4b1e sched/headers: Pr... |
13 |
#include <linux/sched/signal.h> |
5dd43ce2f sched/wait: Split... |
14 |
#include <linux/wait_bit.h> |
10c5db286 fs: move the fiem... |
15 |
#include <linux/fiemap.h> |
1da177e4c Linux-2.6.12-rc2 |
16 17 18 19 20 |
#include <asm/div64.h> #include "cifsfs.h" #include "cifspdu.h" #include "cifsglob.h" #include "cifsproto.h" |
6a5f6592a SMB311: Add suppo... |
21 |
#include "smb2proto.h" |
1da177e4c Linux-2.6.12-rc2 |
22 23 |
#include "cifs_debug.h" #include "cifs_fs_sb.h" |
2baa26825 Remap reserved po... |
24 |
#include "cifs_unicode.h" |
9451a9a52 cifs: define inod... |
25 |
#include "fscache.h" |
8401e9367 cifs: remove [gu]... |
26 |
#include "fs_context.h" |
087f757b0 cifs: add shutdow... |
27 |
#include "cifs_ioctl.h" |
70eff55d2 [CIFS] factoring ... |
28 |
|
01c64feac CIFS: Use d_autom... |
29 |
static void cifs_set_ops(struct inode *inode) |
70eff55d2 [CIFS] factoring ... |
30 31 32 33 34 35 36 37 38 39 40 |
{ struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); switch (inode->i_mode & S_IFMT) { case S_IFREG: inode->i_op = &cifs_file_inode_ops; if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) inode->i_fop = &cifs_file_direct_nobrl_ops; else inode->i_fop = &cifs_file_direct_ops; |
8be7e6ba1 CIFS: Implement c... |
41 42 43 44 45 |
} else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO) { if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) inode->i_fop = &cifs_file_strict_nobrl_ops; else inode->i_fop = &cifs_file_strict_ops; |
70eff55d2 [CIFS] factoring ... |
46 47 48 49 50 |
} else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) inode->i_fop = &cifs_file_nobrl_ops; else { /* not direct, send byte range locks */ inode->i_fop = &cifs_file_ops; } |
70eff55d2 [CIFS] factoring ... |
51 |
/* check if server can support readpages */ |
1f641d941 cifs: improve rea... |
52 |
if (cifs_sb_master_tcon(cifs_sb)->ses->server->max_read < |
09cbfeaf1 mm, fs: get rid o... |
53 |
PAGE_SIZE + MAX_CIFS_HDR_SIZE) |
70eff55d2 [CIFS] factoring ... |
54 55 56 57 58 |
inode->i_data.a_ops = &cifs_addr_ops_smallbuf; else inode->i_data.a_ops = &cifs_addr_ops; break; case S_IFDIR: |
bc5b6e24a [CIFS] Fix build ... |
59 |
#ifdef CONFIG_CIFS_DFS_UPCALL |
01c64feac CIFS: Use d_autom... |
60 |
if (IS_AUTOMOUNT(inode)) { |
7962670e6 [CIFS] DFS patch... |
61 62 |
inode->i_op = &cifs_dfs_referral_inode_operations; } else { |
bc5b6e24a [CIFS] Fix build ... |
63 64 65 |
#else /* NO DFS support, treat as a directory */ { #endif |
7962670e6 [CIFS] DFS patch... |
66 67 68 |
inode->i_op = &cifs_dir_inode_ops; inode->i_fop = &cifs_dir_ops; } |
70eff55d2 [CIFS] factoring ... |
69 70 71 72 73 74 75 76 77 |
break; case S_IFLNK: inode->i_op = &cifs_symlink_inode_ops; break; default: init_special_inode(inode, inode->i_mode, inode->i_rdev); break; } } |
df2cf170c cifs: overhaul ci... |
78 79 80 81 82 83 84 |
/* check inode attributes against fattr. If they don't match, tag the * inode for cache invalidation */ static void cifs_revalidate_cache(struct inode *inode, struct cifs_fattr *fattr) { struct cifsInodeInfo *cifs_i = CIFS_I(inode); |
f96637be0 [CIFS] cifs: Rena... |
85 86 87 |
cifs_dbg(FYI, "%s: revalidating inode %llu ", __func__, cifs_i->uniqueid); |
df2cf170c cifs: overhaul ci... |
88 89 |
if (inode->i_state & I_NEW) { |
f96637be0 [CIFS] cifs: Rena... |
90 91 92 |
cifs_dbg(FYI, "%s: inode %llu is new ", __func__, cifs_i->uniqueid); |
df2cf170c cifs: overhaul ci... |
93 94 95 96 |
return; } /* don't bother with revalidation if we have an oplock */ |
18cceb6a7 CIFS: Replace cli... |
97 |
if (CIFS_CACHE_READ(cifs_i)) { |
f96637be0 [CIFS] cifs: Rena... |
98 99 100 |
cifs_dbg(FYI, "%s: inode %llu is oplocked ", __func__, cifs_i->uniqueid); |
df2cf170c cifs: overhaul ci... |
101 102 103 104 |
return; } /* revalidate if mtime or size have changed */ |
918c90098 fs: cifs: Delete ... |
105 |
fattr->cf_mtime = timestamp_truncate(fattr->cf_mtime, inode); |
95390201e cifs: use timespe... |
106 |
if (timespec64_equal(&inode->i_mtime, &fattr->cf_mtime) && |
df2cf170c cifs: overhaul ci... |
107 |
cifs_i->server_eof == fattr->cf_eof) { |
f96637be0 [CIFS] cifs: Rena... |
108 109 110 |
cifs_dbg(FYI, "%s: inode %llu is unchanged ", __func__, cifs_i->uniqueid); |
df2cf170c cifs: overhaul ci... |
111 112 |
return; } |
f96637be0 [CIFS] cifs: Rena... |
113 114 115 |
cifs_dbg(FYI, "%s: invalidating inode %llu mapping ", __func__, cifs_i->uniqueid); |
aff8d5ca7 cifs: convert boo... |
116 |
set_bit(CIFS_INO_INVALID_MAPPING, &cifs_i->flags); |
df2cf170c cifs: overhaul ci... |
117 |
} |
74d290da4 [CIFS] Provide sa... |
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
/* * copy nlink to the inode, unless it wasn't provided. Provide * sane values if we don't have an existing one and none was provided */ static void cifs_nlink_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr) { /* * if we're in a situation where we can't trust what we * got from the server (readdir, some non-unix cases) * fake reasonable values */ if (fattr->cf_flags & CIFS_FATTR_UNKNOWN_NLINK) { /* only provide fake values on a new inode */ if (inode->i_state & I_NEW) { if (fattr->cf_cifsattrs & ATTR_DIRECTORY) set_nlink(inode, 2); else set_nlink(inode, 1); } return; } /* we trust the server, so update it */ set_nlink(inode, fattr->cf_nlink); } |
cc0bad755 cifs: add new cif... |
144 |
/* populate an inode with info from a cifs_fattr struct */ |
4d66952a2 cifs: have cifs_f... |
145 |
int |
cc0bad755 cifs: add new cif... |
146 |
cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr) |
75f12983d [CIFS] consolidat... |
147 |
{ |
cc0bad755 cifs: add new cif... |
148 |
struct cifsInodeInfo *cifs_i = CIFS_I(inode); |
0b8f18e35 cifs: convert cif... |
149 |
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
cc0bad755 cifs: add new cif... |
150 |
|
4d66952a2 cifs: have cifs_f... |
151 152 153 154 155 |
if (!(inode->i_state & I_NEW) && unlikely(inode_wrong_type(inode, fattr->cf_mode))) { CIFS_I(inode)->time = 0; /* force reval */ return -ESTALE; } |
df2cf170c cifs: overhaul ci... |
156 |
cifs_revalidate_cache(inode, fattr); |
b7ca69289 CIFS: Protect i_n... |
157 |
spin_lock(&inode->i_lock); |
918c90098 fs: cifs: Delete ... |
158 159 160 |
fattr->cf_mtime = timestamp_truncate(fattr->cf_mtime, inode); fattr->cf_atime = timestamp_truncate(fattr->cf_atime, inode); fattr->cf_ctime = timestamp_truncate(fattr->cf_ctime, inode); |
9b9c5bea0 cifs: do not retu... |
161 |
/* we do not want atime to be less than mtime, it broke some apps */ |
69738cfdf fs: cifs: Fix ati... |
162 |
if (timespec64_compare(&fattr->cf_atime, &fattr->cf_mtime) < 0) |
9b9c5bea0 cifs: do not retu... |
163 164 165 |
inode->i_atime = fattr->cf_mtime; else inode->i_atime = fattr->cf_atime; |
95390201e cifs: use timespe... |
166 167 |
inode->i_mtime = fattr->cf_mtime; inode->i_ctime = fattr->cf_ctime; |
cc0bad755 cifs: add new cif... |
168 |
inode->i_rdev = fattr->cf_rdev; |
74d290da4 [CIFS] Provide sa... |
169 |
cifs_nlink_fattr_to_inode(inode, fattr); |
cc0bad755 cifs: add new cif... |
170 171 |
inode->i_uid = fattr->cf_uid; inode->i_gid = fattr->cf_gid; |
0b8f18e35 cifs: convert cif... |
172 173 174 175 |
/* if dynperm is set, don't clobber existing mode */ if (inode->i_state & I_NEW || !(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) inode->i_mode = fattr->cf_mode; |
cc0bad755 cifs: add new cif... |
176 |
cifs_i->cifsAttrs = fattr->cf_cifsattrs; |
75f12983d [CIFS] consolidat... |
177 |
|
0b8f18e35 cifs: convert cif... |
178 179 180 181 |
if (fattr->cf_flags & CIFS_FATTR_NEED_REVAL) cifs_i->time = 0; else cifs_i->time = jiffies; |
aff8d5ca7 cifs: convert boo... |
182 183 184 185 |
if (fattr->cf_flags & CIFS_FATTR_DELETE_PENDING) set_bit(CIFS_INO_DELETE_PENDING, &cifs_i->flags); else clear_bit(CIFS_INO_DELETE_PENDING, &cifs_i->flags); |
cc0bad755 cifs: add new cif... |
186 |
|
835a36ca4 cifs: set server_... |
187 |
cifs_i->server_eof = fattr->cf_eof; |
cc0bad755 cifs: add new cif... |
188 189 190 191 |
/* * Can't safely change the file size here if the client is writing to * it due to potential races. */ |
cc0bad755 cifs: add new cif... |
192 193 194 195 196 197 198 199 200 201 202 |
if (is_size_safe_to_change(cifs_i, fattr->cf_eof)) { i_size_write(inode, fattr->cf_eof); /* * i_blocks is not related to (i_size / i_blksize), * but instead 512 byte (2**9) size is required for * calculating num blocks. */ inode->i_blocks = (512 - 1 + fattr->cf_bytes) >> 9; } spin_unlock(&inode->i_lock); |
01c64feac CIFS: Use d_autom... |
203 204 |
if (fattr->cf_flags & CIFS_FATTR_DFS_REFERRAL) inode->i_flags |= S_AUTOMOUNT; |
c2b93e069 cifs: only set op... |
205 206 |
if (inode->i_state & I_NEW) cifs_set_ops(inode); |
4d66952a2 cifs: have cifs_f... |
207 |
return 0; |
cc0bad755 cifs: add new cif... |
208 |
} |
4065c802d cifs: fix noserve... |
209 210 211 212 213 214 215 216 217 218 |
void cifs_fill_uniqueid(struct super_block *sb, struct cifs_fattr *fattr) { struct cifs_sb_info *cifs_sb = CIFS_SB(sb); if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) return; fattr->cf_uniqueid = iunique(sb, ROOT_I); } |
cc0bad755 cifs: add new cif... |
219 220 221 222 223 224 225 226 227 228 229 230 231 |
/* Fill a cifs_fattr struct with info from FILE_UNIX_BASIC_INFO. */ void cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, FILE_UNIX_BASIC_INFO *info, struct cifs_sb_info *cifs_sb) { memset(fattr, 0, sizeof(*fattr)); fattr->cf_uniqueid = le64_to_cpu(info->UniqueId); fattr->cf_bytes = le64_to_cpu(info->NumOfBytes); fattr->cf_eof = le64_to_cpu(info->EndOfFile); fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime); fattr->cf_mtime = cifs_NTtimeToUnix(info->LastModificationTime); fattr->cf_ctime = cifs_NTtimeToUnix(info->LastStatusChange); |
6e70e26dc SMB3: handle new ... |
232 |
/* old POSIX extensions don't get create time */ |
cc0bad755 cifs: add new cif... |
233 |
fattr->cf_mode = le64_to_cpu(info->Permissions); |
75f12983d [CIFS] consolidat... |
234 235 236 237 238 |
/* * Since we set the inode type below we need to mask off * to avoid strange results if bits set above. */ |
cc0bad755 cifs: add new cif... |
239 |
fattr->cf_mode &= ~S_IFMT; |
75f12983d [CIFS] consolidat... |
240 241 |
switch (le32_to_cpu(info->Type)) { case UNIX_FILE: |
cc0bad755 cifs: add new cif... |
242 243 |
fattr->cf_mode |= S_IFREG; fattr->cf_dtype = DT_REG; |
75f12983d [CIFS] consolidat... |
244 245 |
break; case UNIX_SYMLINK: |
cc0bad755 cifs: add new cif... |
246 247 |
fattr->cf_mode |= S_IFLNK; fattr->cf_dtype = DT_LNK; |
75f12983d [CIFS] consolidat... |
248 249 |
break; case UNIX_DIR: |
cc0bad755 cifs: add new cif... |
250 251 |
fattr->cf_mode |= S_IFDIR; fattr->cf_dtype = DT_DIR; |
75f12983d [CIFS] consolidat... |
252 253 |
break; case UNIX_CHARDEV: |
cc0bad755 cifs: add new cif... |
254 255 256 257 |
fattr->cf_mode |= S_IFCHR; fattr->cf_dtype = DT_CHR; fattr->cf_rdev = MKDEV(le64_to_cpu(info->DevMajor), le64_to_cpu(info->DevMinor) & MINORMASK); |
75f12983d [CIFS] consolidat... |
258 259 |
break; case UNIX_BLOCKDEV: |
cc0bad755 cifs: add new cif... |
260 261 262 263 |
fattr->cf_mode |= S_IFBLK; fattr->cf_dtype = DT_BLK; fattr->cf_rdev = MKDEV(le64_to_cpu(info->DevMajor), le64_to_cpu(info->DevMinor) & MINORMASK); |
75f12983d [CIFS] consolidat... |
264 265 |
break; case UNIX_FIFO: |
cc0bad755 cifs: add new cif... |
266 267 |
fattr->cf_mode |= S_IFIFO; fattr->cf_dtype = DT_FIFO; |
75f12983d [CIFS] consolidat... |
268 269 |
break; case UNIX_SOCKET: |
cc0bad755 cifs: add new cif... |
270 271 |
fattr->cf_mode |= S_IFSOCK; fattr->cf_dtype = DT_SOCK; |
75f12983d [CIFS] consolidat... |
272 273 274 |
break; default: /* safest to call it a file if we do not know */ |
cc0bad755 cifs: add new cif... |
275 276 |
fattr->cf_mode |= S_IFREG; fattr->cf_dtype = DT_REG; |
f96637be0 [CIFS] cifs: Rena... |
277 278 |
cifs_dbg(FYI, "unknown type %d ", le32_to_cpu(info->Type)); |
75f12983d [CIFS] consolidat... |
279 280 |
break; } |
8401e9367 cifs: remove [gu]... |
281 |
fattr->cf_uid = cifs_sb->ctx->linux_uid; |
46bbc25f9 cifs: Override un... |
282 283 |
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)) { u64 id = le64_to_cpu(info->Uid); |
4a2c8cf56 cifs: Convert str... |
284 285 286 287 288 |
if (id < ((uid_t)-1)) { kuid_t uid = make_kuid(&init_user_ns, id); if (uid_valid(uid)) fattr->cf_uid = uid; } |
46bbc25f9 cifs: Override un... |
289 290 |
} |
8401e9367 cifs: remove [gu]... |
291 |
fattr->cf_gid = cifs_sb->ctx->linux_gid; |
46bbc25f9 cifs: Override un... |
292 293 |
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)) { u64 id = le64_to_cpu(info->Gid); |
4a2c8cf56 cifs: Convert str... |
294 295 296 297 298 |
if (id < ((gid_t)-1)) { kgid_t gid = make_kgid(&init_user_ns, id); if (gid_valid(gid)) fattr->cf_gid = gid; } |
46bbc25f9 cifs: Override un... |
299 |
} |
75f12983d [CIFS] consolidat... |
300 |
|
cc0bad755 cifs: add new cif... |
301 |
fattr->cf_nlink = le64_to_cpu(info->Nlinks); |
75f12983d [CIFS] consolidat... |
302 |
} |
b9a3260f2 [CIFS] Enable DFS... |
303 |
/* |
cc0bad755 cifs: add new cif... |
304 305 306 307 308 |
* Fill a cifs_fattr struct with fake inode info. * * Needed to setup cifs_fattr data for the directory which is the * junction to the new submount (ie to setup the fake directory * which represents a DFS referral). |
b9a3260f2 [CIFS] Enable DFS... |
309 |
*/ |
f1230c979 [CIFS] fix sparse... |
310 |
static void |
cc0bad755 cifs: add new cif... |
311 |
cifs_create_dfs_fattr(struct cifs_fattr *fattr, struct super_block *sb) |
0e4bbde94 [CIFS] Enable DFS... |
312 |
{ |
cc0bad755 cifs: add new cif... |
313 |
struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
0e4bbde94 [CIFS] Enable DFS... |
314 |
|
f96637be0 [CIFS] cifs: Rena... |
315 316 |
cifs_dbg(FYI, "creating fake fattr for DFS referral "); |
cc0bad755 cifs: add new cif... |
317 318 319 |
memset(fattr, 0, sizeof(*fattr)); fattr->cf_mode = S_IFDIR | S_IXUGO | S_IRWXU; |
8401e9367 cifs: remove [gu]... |
320 321 |
fattr->cf_uid = cifs_sb->ctx->linux_uid; fattr->cf_gid = cifs_sb->ctx->linux_gid; |
918c90098 fs: cifs: Delete ... |
322 |
ktime_get_coarse_real_ts64(&fattr->cf_mtime); |
e37fea58f fs: cifs: replace... |
323 |
fattr->cf_atime = fattr->cf_ctime = fattr->cf_mtime; |
cc0bad755 cifs: add new cif... |
324 |
fattr->cf_nlink = 2; |
97aa495a8 cifs: address tri... |
325 |
fattr->cf_flags = CIFS_FATTR_DFS_REFERRAL; |
0e4bbde94 [CIFS] Enable DFS... |
326 |
} |
4ad650445 CIFS: Move guery ... |
327 328 |
static int cifs_get_file_info_unix(struct file *filp) |
abab095d1 cifs: add cifs_re... |
329 330 |
{ int rc; |
6d5786a34 CIFS: Rename Get/... |
331 |
unsigned int xid; |
abab095d1 cifs: add cifs_re... |
332 333 |
FILE_UNIX_BASIC_INFO find_data; struct cifs_fattr fattr; |
496ad9aa8 new helper: file_... |
334 |
struct inode *inode = file_inode(filp); |
abab095d1 cifs: add cifs_re... |
335 |
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
c21dfb699 fs/cifs: Remove u... |
336 |
struct cifsFileInfo *cfile = filp->private_data; |
96daf2b09 [CIFS] Rename thr... |
337 |
struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); |
abab095d1 cifs: add cifs_re... |
338 |
|
6d5786a34 CIFS: Rename Get/... |
339 |
xid = get_xid(); |
4b4de76e3 CIFS: Replace net... |
340 |
rc = CIFSSMBUnixQFileInfo(xid, tcon, cfile->fid.netfid, &find_data); |
abab095d1 cifs: add cifs_re... |
341 342 343 344 345 |
if (!rc) { cifs_unix_basic_to_fattr(&fattr, &find_data, cifs_sb); } else if (rc == -EREMOTE) { cifs_create_dfs_fattr(&fattr, inode->i_sb); rc = 0; |
e39df2416 cifs: fix SMB1 er... |
346 347 |
} else goto cifs_gfiunix_out; |
abab095d1 cifs: add cifs_re... |
348 |
|
4d66952a2 cifs: have cifs_f... |
349 |
rc = cifs_fattr_to_inode(inode, &fattr); |
e39df2416 cifs: fix SMB1 er... |
350 351 |
cifs_gfiunix_out: |
6d5786a34 CIFS: Rename Get/... |
352 |
free_xid(xid); |
abab095d1 cifs: add cifs_re... |
353 354 |
return rc; } |
1da177e4c Linux-2.6.12-rc2 |
355 |
int cifs_get_inode_info_unix(struct inode **pinode, |
cc0bad755 cifs: add new cif... |
356 |
const unsigned char *full_path, |
6d5786a34 CIFS: Rename Get/... |
357 |
struct super_block *sb, unsigned int xid) |
1da177e4c Linux-2.6.12-rc2 |
358 |
{ |
cc0bad755 cifs: add new cif... |
359 |
int rc; |
0e4bbde94 [CIFS] Enable DFS... |
360 |
FILE_UNIX_BASIC_INFO find_data; |
cc0bad755 cifs: add new cif... |
361 |
struct cifs_fattr fattr; |
96daf2b09 [CIFS] Rename thr... |
362 |
struct cifs_tcon *tcon; |
7ffec3724 cifs: add refcoun... |
363 |
struct tcon_link *tlink; |
1da177e4c Linux-2.6.12-rc2 |
364 |
struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
1da177e4c Linux-2.6.12-rc2 |
365 |
|
f96637be0 [CIFS] cifs: Rena... |
366 367 |
cifs_dbg(FYI, "Getting info on %s ", full_path); |
7962670e6 [CIFS] DFS patch... |
368 |
|
7ffec3724 cifs: add refcoun... |
369 370 371 372 |
tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) return PTR_ERR(tlink); tcon = tlink_tcon(tlink); |
1da177e4c Linux-2.6.12-rc2 |
373 |
/* could have done a find first instead but this returns more info */ |
cc0bad755 cifs: add new cif... |
374 |
rc = CIFSSMBUnixQPathInfo(xid, tcon, full_path, &find_data, |
bc8ebdc4f Fix that several ... |
375 |
cifs_sb->local_nls, cifs_remap(cifs_sb)); |
7ffec3724 cifs: add refcoun... |
376 |
cifs_put_tlink(tlink); |
e911d0cc8 cifs: fix inode l... |
377 |
|
cc0bad755 cifs: add new cif... |
378 379 380 381 382 383 384 385 |
if (!rc) { cifs_unix_basic_to_fattr(&fattr, &find_data, cifs_sb); } else if (rc == -EREMOTE) { cifs_create_dfs_fattr(&fattr, sb); rc = 0; } else { return rc; } |
1da177e4c Linux-2.6.12-rc2 |
386 |
|
1b12b9c15 cifs: use Minshal... |
387 388 |
/* check for Minshall+French symlinks */ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) { |
cb084b1a9 cifs: Rename MF s... |
389 390 |
int tmprc = check_mf_symlink(xid, tcon, cifs_sb, &fattr, full_path); |
1b12b9c15 cifs: use Minshal... |
391 |
if (tmprc) |
cb084b1a9 cifs: Rename MF s... |
392 393 |
cifs_dbg(FYI, "check_mf_symlink: %d ", tmprc); |
1b12b9c15 cifs: use Minshal... |
394 |
} |
0e4bbde94 [CIFS] Enable DFS... |
395 |
if (*pinode == NULL) { |
cc0bad755 cifs: add new cif... |
396 |
/* get new inode */ |
4065c802d cifs: fix noserve... |
397 |
cifs_fill_uniqueid(sb, &fattr); |
cc0bad755 cifs: add new cif... |
398 399 |
*pinode = cifs_iget(sb, &fattr); if (!*pinode) |
0e4bbde94 [CIFS] Enable DFS... |
400 |
rc = -ENOMEM; |
cc0bad755 cifs: add new cif... |
401 402 |
} else { /* we already have inode, update it */ |
7196ac113 Fix to check Uniq... |
403 404 405 406 |
/* if uniqueid is different, return error */ if (unlikely(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM && CIFS_I(*pinode)->uniqueid != fattr.cf_uniqueid)) { |
c82e5ac7f CIFS: Force reval... |
407 |
CIFS_I(*pinode)->time = 0; /* force reval */ |
7196ac113 Fix to check Uniq... |
408 409 410 411 412 |
rc = -ESTALE; goto cgiiu_exit; } /* if filetype is different, return error */ |
4d66952a2 cifs: have cifs_f... |
413 |
rc = cifs_fattr_to_inode(*pinode, &fattr); |
0e4bbde94 [CIFS] Enable DFS... |
414 |
} |
1da177e4c Linux-2.6.12-rc2 |
415 |
|
7196ac113 Fix to check Uniq... |
416 |
cgiiu_exit: |
1da177e4c Linux-2.6.12-rc2 |
417 418 |
return rc; } |
0b8f18e35 cifs: convert cif... |
419 |
static int |
0360d605a CIFS: Remove extr... |
420 |
cifs_sfu_type(struct cifs_fattr *fattr, const char *path, |
6d5786a34 CIFS: Rename Get/... |
421 |
struct cifs_sb_info *cifs_sb, unsigned int xid) |
d6e2f2a4c [CIFS] Recognize ... |
422 423 |
{ int rc; |
db8b631d4 Allow mknod and m... |
424 |
__u32 oplock; |
7ffec3724 cifs: add refcoun... |
425 |
struct tcon_link *tlink; |
96daf2b09 [CIFS] Rename thr... |
426 |
struct cifs_tcon *tcon; |
d81b8a40e CIFS: Cleanup cif... |
427 428 |
struct cifs_fid fid; struct cifs_open_parms oparms; |
7c06514af cifs: multichanne... |
429 |
struct cifs_io_parms io_parms = {0}; |
86c96b4bb [CIFS] Fix mknod ... |
430 |
char buf[24]; |
d6e2f2a4c [CIFS] Recognize ... |
431 |
unsigned int bytes_read; |
fb8c4b14d [CIFS] whitespace... |
432 |
char *pbuf; |
0360d605a CIFS: Remove extr... |
433 |
int buf_type = CIFS_NO_BUFFER; |
d6e2f2a4c [CIFS] Recognize ... |
434 435 |
pbuf = buf; |
0b8f18e35 cifs: convert cif... |
436 437 438 439 440 |
fattr->cf_mode &= ~S_IFMT; if (fattr->cf_eof == 0) { fattr->cf_mode |= S_IFIFO; fattr->cf_dtype = DT_FIFO; |
d6e2f2a4c [CIFS] Recognize ... |
441 |
return 0; |
0b8f18e35 cifs: convert cif... |
442 443 444 |
} else if (fattr->cf_eof < 8) { fattr->cf_mode |= S_IFREG; fattr->cf_dtype = DT_REG; |
d6e2f2a4c [CIFS] Recognize ... |
445 446 |
return -EINVAL; /* EOPNOTSUPP? */ } |
50c2f7538 [CIFS] whitespace... |
447 |
|
7ffec3724 cifs: add refcoun... |
448 449 450 451 |
tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) return PTR_ERR(tlink); tcon = tlink_tcon(tlink); |
d81b8a40e CIFS: Cleanup cif... |
452 453 454 |
oparms.tcon = tcon; oparms.cifs_sb = cifs_sb; oparms.desired_access = GENERIC_READ; |
0f060936e SMB3: Backup inte... |
455 |
oparms.create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR); |
d81b8a40e CIFS: Cleanup cif... |
456 457 458 459 |
oparms.disposition = FILE_OPEN; oparms.path = path; oparms.fid = &fid; oparms.reconnect = false; |
db8b631d4 Allow mknod and m... |
460 461 462 463 464 |
if (tcon->ses->server->oplocks) oplock = REQ_OPLOCK; else oplock = 0; rc = tcon->ses->server->ops->open(xid, &oparms, &oplock, NULL); |
0360d605a CIFS: Remove extr... |
465 |
if (rc) { |
db8b631d4 Allow mknod and m... |
466 467 |
cifs_dbg(FYI, "check sfu type of %s, open rc = %d ", path, rc); |
0360d605a CIFS: Remove extr... |
468 469 470 471 472 |
cifs_put_tlink(tlink); return rc; } /* Read header */ |
d81b8a40e CIFS: Cleanup cif... |
473 |
io_parms.netfid = fid.netfid; |
0360d605a CIFS: Remove extr... |
474 475 476 477 |
io_parms.pid = current->tgid; io_parms.tcon = tcon; io_parms.offset = 0; io_parms.length = 24; |
db8b631d4 Allow mknod and m... |
478 479 |
rc = tcon->ses->server->ops->sync_read(xid, &fid, &io_parms, &bytes_read, &pbuf, &buf_type); |
0360d605a CIFS: Remove extr... |
480 481 482 483 484 485 486 487 488 489 490 491 492 |
if ((rc == 0) && (bytes_read >= 8)) { if (memcmp("IntxBLK", pbuf, 8) == 0) { cifs_dbg(FYI, "Block device "); fattr->cf_mode |= S_IFBLK; fattr->cf_dtype = DT_BLK; if (bytes_read == 24) { /* we have enough to decode dev num */ __u64 mjr; /* major */ __u64 mnr; /* minor */ mjr = le64_to_cpu(*(__le64 *)(pbuf+8)); mnr = le64_to_cpu(*(__le64 *)(pbuf+16)); fattr->cf_rdev = MKDEV(mjr, mnr); |
86c96b4bb [CIFS] Fix mknod ... |
493 |
} |
0360d605a CIFS: Remove extr... |
494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 |
} else if (memcmp("IntxCHR", pbuf, 8) == 0) { cifs_dbg(FYI, "Char device "); fattr->cf_mode |= S_IFCHR; fattr->cf_dtype = DT_CHR; if (bytes_read == 24) { /* we have enough to decode dev num */ __u64 mjr; /* major */ __u64 mnr; /* minor */ mjr = le64_to_cpu(*(__le64 *)(pbuf+8)); mnr = le64_to_cpu(*(__le64 *)(pbuf+16)); fattr->cf_rdev = MKDEV(mjr, mnr); } } else if (memcmp("IntxLNK", pbuf, 7) == 0) { cifs_dbg(FYI, "Symlink "); fattr->cf_mode |= S_IFLNK; fattr->cf_dtype = DT_LNK; |
3020a1f58 [CIFS] Fix schedu... |
512 |
} else { |
0360d605a CIFS: Remove extr... |
513 |
fattr->cf_mode |= S_IFREG; /* file? */ |
0b8f18e35 cifs: convert cif... |
514 |
fattr->cf_dtype = DT_REG; |
0360d605a CIFS: Remove extr... |
515 |
rc = -EOPNOTSUPP; |
fb8c4b14d [CIFS] whitespace... |
516 |
} |
0360d605a CIFS: Remove extr... |
517 518 519 520 |
} else { fattr->cf_mode |= S_IFREG; /* then it is a file */ fattr->cf_dtype = DT_REG; rc = -EOPNOTSUPP; /* or some unknown SFU type */ |
d6e2f2a4c [CIFS] Recognize ... |
521 |
} |
db8b631d4 Allow mknod and m... |
522 523 |
tcon->ses->server->ops->close(xid, tcon, &fid); |
7ffec3724 cifs: add refcoun... |
524 |
cifs_put_tlink(tlink); |
d6e2f2a4c [CIFS] Recognize ... |
525 |
return rc; |
d6e2f2a4c [CIFS] Recognize ... |
526 |
} |
9e294f1c4 [CIFS] Recognize ... |
527 |
#define SFBITS_MASK (S_ISVTX | S_ISGID | S_ISUID) /* SETFILEBITS valid bits */ |
0b8f18e35 cifs: convert cif... |
528 529 530 531 532 533 |
/* * Fetch mode bits as provided by SFU. * * FIXME: Doesn't this clobber the type bit we got from cifs_sfu_type ? */ static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path, |
6d5786a34 CIFS: Rename Get/... |
534 |
struct cifs_sb_info *cifs_sb, unsigned int xid) |
9e294f1c4 [CIFS] Recognize ... |
535 |
{ |
3020a1f58 [CIFS] Fix schedu... |
536 |
#ifdef CONFIG_CIFS_XATTR |
9e294f1c4 [CIFS] Recognize ... |
537 538 539 |
ssize_t rc; char ea_value[4]; __u32 mode; |
7ffec3724 cifs: add refcoun... |
540 |
struct tcon_link *tlink; |
96daf2b09 [CIFS] Rename thr... |
541 |
struct cifs_tcon *tcon; |
7ffec3724 cifs: add refcoun... |
542 543 544 545 546 |
tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) return PTR_ERR(tlink); tcon = tlink_tcon(tlink); |
9e294f1c4 [CIFS] Recognize ... |
547 |
|
d979f3b0a Add protocol spec... |
548 549 550 551 552 553 554 |
if (tcon->ses->server->ops->query_all_EAs == NULL) { cifs_put_tlink(tlink); return -EOPNOTSUPP; } rc = tcon->ses->server->ops->query_all_EAs(xid, tcon, path, "SETFILEBITS", ea_value, 4 /* size of buf */, |
67b4c889c [CIFS] Minor clea... |
555 |
cifs_sb); |
7ffec3724 cifs: add refcoun... |
556 |
cifs_put_tlink(tlink); |
4523cc304 [CIFS] UID/GID ov... |
557 |
if (rc < 0) |
9e294f1c4 [CIFS] Recognize ... |
558 559 560 |
return (int)rc; else if (rc > 3) { mode = le32_to_cpu(*((__le32 *)ea_value)); |
0b8f18e35 cifs: convert cif... |
561 |
fattr->cf_mode &= ~SFBITS_MASK; |
f96637be0 [CIFS] cifs: Rena... |
562 563 564 |
cifs_dbg(FYI, "special bits 0%o org mode 0%o ", mode, fattr->cf_mode); |
0b8f18e35 cifs: convert cif... |
565 |
fattr->cf_mode = (mode & SFBITS_MASK) | fattr->cf_mode; |
f96637be0 [CIFS] cifs: Rena... |
566 567 |
cifs_dbg(FYI, "special mode bits 0%o ", mode); |
9e294f1c4 [CIFS] Recognize ... |
568 |
} |
0b8f18e35 cifs: convert cif... |
569 570 |
return 0; |
3020a1f58 [CIFS] Fix schedu... |
571 572 573 |
#else return -EOPNOTSUPP; #endif |
9e294f1c4 [CIFS] Recognize ... |
574 |
} |
6a5f6592a SMB311: Add suppo... |
575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 |
/* Fill a cifs_fattr struct with info from POSIX info struct */ static void smb311_posix_info_to_fattr(struct cifs_fattr *fattr, struct smb311_posix_qinfo *info, struct super_block *sb, bool adjust_tz, bool symlink) { struct cifs_sb_info *cifs_sb = CIFS_SB(sb); struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); memset(fattr, 0, sizeof(*fattr)); /* no fattr->flags to set */ fattr->cf_cifsattrs = le32_to_cpu(info->DosAttributes); fattr->cf_uniqueid = le64_to_cpu(info->Inode); if (info->LastAccessTime) fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime); else ktime_get_coarse_real_ts64(&fattr->cf_atime); fattr->cf_ctime = cifs_NTtimeToUnix(info->ChangeTime); fattr->cf_mtime = cifs_NTtimeToUnix(info->LastWriteTime); if (adjust_tz) { fattr->cf_ctime.tv_sec += tcon->ses->server->timeAdj; fattr->cf_mtime.tv_sec += tcon->ses->server->timeAdj; } fattr->cf_eof = le64_to_cpu(info->EndOfFile); fattr->cf_bytes = le64_to_cpu(info->AllocationSize); fattr->cf_createtime = le64_to_cpu(info->CreationTime); fattr->cf_nlink = le32_to_cpu(info->HardLinks); fattr->cf_mode = (umode_t) le32_to_cpu(info->Mode); /* The srv fs device id is overridden on network mount so setting rdev isn't needed here */ /* fattr->cf_rdev = le32_to_cpu(info->DeviceId); */ if (symlink) { fattr->cf_mode |= S_IFLNK; fattr->cf_dtype = DT_LNK; } else if (fattr->cf_cifsattrs & ATTR_DIRECTORY) { fattr->cf_mode |= S_IFDIR; fattr->cf_dtype = DT_DIR; } else { /* file */ fattr->cf_mode |= S_IFREG; fattr->cf_dtype = DT_REG; } /* else if reparse point ... TODO: add support for FIFO and blk dev; special file types */ |
8401e9367 cifs: remove [gu]... |
622 623 |
fattr->cf_uid = cifs_sb->ctx->linux_uid; /* TODO: map uid and gid from SID */ fattr->cf_gid = cifs_sb->ctx->linux_gid; |
6a5f6592a SMB311: Add suppo... |
624 625 626 627 628 |
cifs_dbg(FYI, "POSIX query info: mode 0x%x uniqueid 0x%llx nlink %d ", fattr->cf_mode, fattr->cf_uniqueid, fattr->cf_nlink); } |
0b8f18e35 cifs: convert cif... |
629 |
/* Fill a cifs_fattr struct with info from FILE_ALL_INFO */ |
f1230c979 [CIFS] fix sparse... |
630 |
static void |
0b8f18e35 cifs: convert cif... |
631 |
cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info, |
e37fea58f fs: cifs: replace... |
632 |
struct super_block *sb, bool adjust_tz, |
2e4564b31 smb3: add support... |
633 |
bool symlink, u32 reparse_tag) |
b9a3260f2 [CIFS] Enable DFS... |
634 |
{ |
e37fea58f fs: cifs: replace... |
635 |
struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
96daf2b09 [CIFS] Rename thr... |
636 |
struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); |
0d424ad0a cifs: add cifs_sb... |
637 |
|
0b8f18e35 cifs: convert cif... |
638 639 640 641 642 643 644 |
memset(fattr, 0, sizeof(*fattr)); fattr->cf_cifsattrs = le32_to_cpu(info->Attributes); if (info->DeletePending) fattr->cf_flags |= CIFS_FATTR_DELETE_PENDING; if (info->LastAccessTime) fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime); |
918c90098 fs: cifs: Delete ... |
645 646 |
else ktime_get_coarse_real_ts64(&fattr->cf_atime); |
0b8f18e35 cifs: convert cif... |
647 648 649 650 651 |
fattr->cf_ctime = cifs_NTtimeToUnix(info->ChangeTime); fattr->cf_mtime = cifs_NTtimeToUnix(info->LastWriteTime); if (adjust_tz) { |
0d424ad0a cifs: add cifs_sb... |
652 653 |
fattr->cf_ctime.tv_sec += tcon->ses->server->timeAdj; fattr->cf_mtime.tv_sec += tcon->ses->server->timeAdj; |
0b8f18e35 cifs: convert cif... |
654 655 656 657 |
} fattr->cf_eof = le64_to_cpu(info->EndOfFile); fattr->cf_bytes = le64_to_cpu(info->AllocationSize); |
20054bd65 cifs: use Creatio... |
658 |
fattr->cf_createtime = le64_to_cpu(info->CreationTime); |
0b8f18e35 cifs: convert cif... |
659 |
|
74d290da4 [CIFS] Provide sa... |
660 |
fattr->cf_nlink = le32_to_cpu(info->NumberOfLinks); |
2e4564b31 smb3: add support... |
661 |
if (reparse_tag == IO_REPARSE_TAG_LX_SYMLINK) { |
8401e9367 cifs: remove [gu]... |
662 |
fattr->cf_mode |= S_IFLNK | cifs_sb->ctx->file_mode; |
2e4564b31 smb3: add support... |
663 664 |
fattr->cf_dtype = DT_LNK; } else if (reparse_tag == IO_REPARSE_TAG_LX_FIFO) { |
8401e9367 cifs: remove [gu]... |
665 |
fattr->cf_mode |= S_IFIFO | cifs_sb->ctx->file_mode; |
2e4564b31 smb3: add support... |
666 667 |
fattr->cf_dtype = DT_FIFO; } else if (reparse_tag == IO_REPARSE_TAG_AF_UNIX) { |
8401e9367 cifs: remove [gu]... |
668 |
fattr->cf_mode |= S_IFSOCK | cifs_sb->ctx->file_mode; |
2e4564b31 smb3: add support... |
669 670 |
fattr->cf_dtype = DT_SOCK; } else if (reparse_tag == IO_REPARSE_TAG_LX_CHR) { |
8401e9367 cifs: remove [gu]... |
671 |
fattr->cf_mode |= S_IFCHR | cifs_sb->ctx->file_mode; |
2e4564b31 smb3: add support... |
672 673 |
fattr->cf_dtype = DT_CHR; } else if (reparse_tag == IO_REPARSE_TAG_LX_BLK) { |
8401e9367 cifs: remove [gu]... |
674 |
fattr->cf_mode |= S_IFBLK | cifs_sb->ctx->file_mode; |
2e4564b31 smb3: add support... |
675 676 |
fattr->cf_dtype = DT_BLK; } else if (symlink) { /* TODO add more reparse tag checks */ |
eb85d94bd CIFS: Fix symboli... |
677 678 679 |
fattr->cf_mode = S_IFLNK; fattr->cf_dtype = DT_LNK; } else if (fattr->cf_cifsattrs & ATTR_DIRECTORY) { |
8401e9367 cifs: remove [gu]... |
680 |
fattr->cf_mode = S_IFDIR | cifs_sb->ctx->dir_mode; |
0b8f18e35 cifs: convert cif... |
681 |
fattr->cf_dtype = DT_DIR; |
6de2ce423 CIFS: Fix mkdir/r... |
682 683 684 685 |
/* * Server can return wrong NumberOfLinks value for directories * when Unix extensions are disabled - fake it. */ |
74d290da4 [CIFS] Provide sa... |
686 687 |
if (!tcon->unix_ext) fattr->cf_flags |= CIFS_FATTR_UNKNOWN_NLINK; |
0b8f18e35 cifs: convert cif... |
688 |
} else { |
8401e9367 cifs: remove [gu]... |
689 |
fattr->cf_mode = S_IFREG | cifs_sb->ctx->file_mode; |
0b8f18e35 cifs: convert cif... |
690 |
fattr->cf_dtype = DT_REG; |
0b8f18e35 cifs: convert cif... |
691 |
|
d0c280d26 cifs: when ATTR_R... |
692 693 694 |
/* clear write bits if ATTR_READONLY is set */ if (fattr->cf_cifsattrs & ATTR_READONLY) fattr->cf_mode &= ~(S_IWUGO); |
0b8f18e35 cifs: convert cif... |
695 |
|
74d290da4 [CIFS] Provide sa... |
696 697 698 699 700 701 |
/* * Don't accept zero nlink from non-unix servers unless * delete is pending. Instead mark it as unknown. */ if ((fattr->cf_nlink < 1) && !tcon->unix_ext && !info->DeletePending) { |
fb4b5f134 cifs: Use #define... |
702 703 704 |
cifs_dbg(VFS, "bogus file nlink value %u ", fattr->cf_nlink); |
74d290da4 [CIFS] Provide sa... |
705 |
fattr->cf_flags |= CIFS_FATTR_UNKNOWN_NLINK; |
6658b9f70 [CIFS] use sensib... |
706 |
} |
6de2ce423 CIFS: Fix mkdir/r... |
707 |
} |
0b8f18e35 cifs: convert cif... |
708 |
|
8401e9367 cifs: remove [gu]... |
709 710 |
fattr->cf_uid = cifs_sb->ctx->linux_uid; fattr->cf_gid = cifs_sb->ctx->linux_gid; |
b9a3260f2 [CIFS] Enable DFS... |
711 |
} |
4ad650445 CIFS: Move guery ... |
712 713 |
static int cifs_get_file_info(struct file *filp) |
abab095d1 cifs: add cifs_re... |
714 715 |
{ int rc; |
6d5786a34 CIFS: Rename Get/... |
716 |
unsigned int xid; |
abab095d1 cifs: add cifs_re... |
717 718 |
FILE_ALL_INFO find_data; struct cifs_fattr fattr; |
496ad9aa8 new helper: file_... |
719 |
struct inode *inode = file_inode(filp); |
c21dfb699 fs/cifs: Remove u... |
720 |
struct cifsFileInfo *cfile = filp->private_data; |
96daf2b09 [CIFS] Rename thr... |
721 |
struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); |
4ad650445 CIFS: Move guery ... |
722 723 724 725 |
struct TCP_Server_Info *server = tcon->ses->server; if (!server->ops->query_file_info) return -ENOSYS; |
abab095d1 cifs: add cifs_re... |
726 |
|
6d5786a34 CIFS: Rename Get/... |
727 |
xid = get_xid(); |
4ad650445 CIFS: Move guery ... |
728 |
rc = server->ops->query_file_info(xid, tcon, &cfile->fid, &find_data); |
42274bb22 CIFS: Fix DFS han... |
729 730 |
switch (rc) { case 0: |
2e4564b31 smb3: add support... |
731 |
/* TODO: add support to query reparse tag */ |
e37fea58f fs: cifs: replace... |
732 |
cifs_all_info_to_fattr(&fattr, &find_data, inode->i_sb, false, |
2e4564b31 smb3: add support... |
733 |
false, 0 /* no reparse tag */); |
42274bb22 CIFS: Fix DFS han... |
734 735 736 737 738 739 740 |
break; case -EREMOTE: cifs_create_dfs_fattr(&fattr, inode->i_sb); rc = 0; break; case -EOPNOTSUPP: case -EINVAL: |
abab095d1 cifs: add cifs_re... |
741 742 |
/* * FIXME: legacy server -- fall back to path-based call? |
ff215713e [CIFS] checkpatch... |
743 744 745 |
* for now, just skip revalidating and mark inode for * immediate reval. */ |
abab095d1 cifs: add cifs_re... |
746 747 |
rc = 0; CIFS_I(inode)->time = 0; |
21ac58f49 cifs: Fix fall-th... |
748 |
goto cgfi_exit; |
42274bb22 CIFS: Fix DFS han... |
749 |
default: |
abab095d1 cifs: add cifs_re... |
750 |
goto cgfi_exit; |
42274bb22 CIFS: Fix DFS han... |
751 |
} |
abab095d1 cifs: add cifs_re... |
752 753 754 755 756 |
/* * don't bother with SFU junk here -- just mark inode as needing * revalidation. */ |
abab095d1 cifs: add cifs_re... |
757 758 |
fattr.cf_uniqueid = CIFS_I(inode)->uniqueid; fattr.cf_flags |= CIFS_FATTR_NEED_REVAL; |
4d66952a2 cifs: have cifs_f... |
759 760 |
/* if filetype is different, return error */ rc = cifs_fattr_to_inode(inode, &fattr); |
abab095d1 cifs: add cifs_re... |
761 |
cgfi_exit: |
6d5786a34 CIFS: Rename Get/... |
762 |
free_xid(xid); |
abab095d1 cifs: add cifs_re... |
763 764 |
return rc; } |
7ea884c77 smb3: Fix root di... |
765 766 767 |
/* Simple function to return a 64 bit hash of string. Rarely called */ static __u64 simple_hashstr(const char *str) { |
3995bbf53 cifs: Use ULL suf... |
768 |
const __u64 hash_mult = 1125899906842597ULL; /* a big enough prime */ |
7ea884c77 smb3: Fix root di... |
769 770 771 772 773 774 775 |
__u64 hash = 0; while (*str) hash = (hash + (__u64) *str++) * hash_mult; return hash; } |
b8f7442bc CIFS: refactor ci... |
776 777 778 779 |
/** * cifs_backup_query_path_info - SMB1 fallback code to get ino * * Fallback code to get file metadata when we don't have access to |
607dfc79c cifs: remove vari... |
780 |
* full_path (EACCES) and have backup creds. |
b8f7442bc CIFS: refactor ci... |
781 |
* |
607dfc79c cifs: remove vari... |
782 783 784 785 786 787 788 |
* @xid: transaction id used to identify original request in logs * @tcon: information about the server share we have mounted * @sb: the superblock stores info such as disk space available * @full_path: name of the file we are getting the metadata for * @resp_buf: will be set to cifs resp buf and needs to be freed with * cifs_buf_release() when done with @data * @data: will be set to search info result buffer |
b8f7442bc CIFS: refactor ci... |
789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 |
*/ static int cifs_backup_query_path_info(int xid, struct cifs_tcon *tcon, struct super_block *sb, const char *full_path, void **resp_buf, FILE_ALL_INFO **data) { struct cifs_sb_info *cifs_sb = CIFS_SB(sb); struct cifs_search_info info = {0}; u16 flags; int rc; *resp_buf = NULL; info.endOfSearch = false; if (tcon->unix_ext) info.info_level = SMB_FIND_FILE_UNIX; else if ((tcon->ses->capabilities & tcon->ses->server->vals->cap_nt_find) == 0) info.info_level = SMB_FIND_FILE_INFO_STANDARD; else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) info.info_level = SMB_FIND_FILE_ID_FULL_DIR_INFO; else /* no srvino useful for fallback to some netapp */ info.info_level = SMB_FIND_FILE_DIRECTORY_INFO; flags = CIFS_SEARCH_CLOSE_ALWAYS | CIFS_SEARCH_CLOSE_AT_END | CIFS_SEARCH_BACKUP_SEARCH; rc = CIFSFindFirst(xid, tcon, full_path, cifs_sb, NULL, flags, &info, false); if (rc) return rc; *resp_buf = (void *)info.ntwrk_buf_start; *data = (FILE_ALL_INFO *)info.srch_entries_start; return 0; } static void cifs_set_fattr_ino(int xid, struct cifs_tcon *tcon, struct super_block *sb, struct inode **inode, const char *full_path, FILE_ALL_INFO *data, struct cifs_fattr *fattr) { struct cifs_sb_info *cifs_sb = CIFS_SB(sb); struct TCP_Server_Info *server = tcon->ses->server; int rc; if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) { if (*inode) fattr->cf_uniqueid = CIFS_I(*inode)->uniqueid; else fattr->cf_uniqueid = iunique(sb, ROOT_I); return; } /* * If we have an inode pass a NULL tcon to ensure we don't * make a round trip to the server. This only works for SMB2+. */ rc = server->ops->get_srv_inum(xid, *inode ? NULL : tcon, cifs_sb, full_path, &fattr->cf_uniqueid, data); if (rc) { /* * If that fails reuse existing ino or generate one * and disable server ones */ if (*inode) fattr->cf_uniqueid = CIFS_I(*inode)->uniqueid; else { fattr->cf_uniqueid = iunique(sb, ROOT_I); cifs_autodisable_serverino(cifs_sb); } return; } /* If no errors, check for zero root inode (invalid) */ if (fattr->cf_uniqueid == 0 && strlen(full_path) == 0) { cifs_dbg(FYI, "Invalid (0) inodenum "); if (*inode) { /* reuse */ fattr->cf_uniqueid = CIFS_I(*inode)->uniqueid; } else { /* make an ino by hashing the UNC */ fattr->cf_flags |= CIFS_FATTR_FAKE_ROOT_INO; fattr->cf_uniqueid = simple_hashstr(tcon->treeName); } } } static inline bool is_inode_cache_good(struct inode *ino) { return ino && CIFS_CACHE_READ(CIFS_I(ino)) && CIFS_I(ino)->time != 0; } |
1208ef1f7 CIFS: Move query ... |
892 |
int |
b8f7442bc CIFS: refactor ci... |
893 894 895 896 |
cifs_get_inode_info(struct inode **inode, const char *full_path, FILE_ALL_INFO *in_data, struct super_block *sb, int xid, |
42eacf9e5 [CIFS] Fix cifsac... |
897 |
const struct cifs_fid *fid) |
1da177e4c Linux-2.6.12-rc2 |
898 |
{ |
b8f7442bc CIFS: refactor ci... |
899 |
|
1208ef1f7 CIFS: Move query ... |
900 901 |
struct cifs_tcon *tcon; struct TCP_Server_Info *server; |
7ffec3724 cifs: add refcoun... |
902 |
struct tcon_link *tlink; |
1da177e4c Linux-2.6.12-rc2 |
903 |
struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
1208ef1f7 CIFS: Move query ... |
904 |
bool adjust_tz = false; |
b8f7442bc CIFS: refactor ci... |
905 |
struct cifs_fattr fattr = {0}; |
2e4564b31 smb3: add support... |
906 |
bool is_reparse_point = false; |
b8f7442bc CIFS: refactor ci... |
907 908 909 910 911 |
FILE_ALL_INFO *data = in_data; FILE_ALL_INFO *tmp_data = NULL; void *smb1_backup_rsp_buf = NULL; int rc = 0; int tmprc = 0; |
2e4564b31 smb3: add support... |
912 |
__u32 reparse_tag = 0; |
1da177e4c Linux-2.6.12-rc2 |
913 |
|
7ffec3724 cifs: add refcoun... |
914 915 916 |
tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) return PTR_ERR(tlink); |
1208ef1f7 CIFS: Move query ... |
917 918 |
tcon = tlink_tcon(tlink); server = tcon->ses->server; |
7ffec3724 cifs: add refcoun... |
919 |
|
b8f7442bc CIFS: refactor ci... |
920 921 922 |
/* * 1. Fetch file metadata if not provided (data) */ |
1da177e4c Linux-2.6.12-rc2 |
923 |
|
b8f7442bc CIFS: refactor ci... |
924 925 |
if (!data) { if (is_inode_cache_good(*inode)) { |
f96637be0 [CIFS] cifs: Rena... |
926 927 |
cifs_dbg(FYI, "No need to revalidate cached inode sizes "); |
b8f7442bc CIFS: refactor ci... |
928 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
929 |
} |
b8f7442bc CIFS: refactor ci... |
930 931 |
tmp_data = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); if (!tmp_data) { |
7ffec3724 cifs: add refcoun... |
932 |
rc = -ENOMEM; |
b8f7442bc CIFS: refactor ci... |
933 |
goto out; |
7ffec3724 cifs: add refcoun... |
934 |
} |
b8f7442bc CIFS: refactor ci... |
935 |
rc = server->ops->query_path_info(xid, tcon, cifs_sb, |
2e4564b31 smb3: add support... |
936 937 |
full_path, tmp_data, &adjust_tz, &is_reparse_point); |
b8f7442bc CIFS: refactor ci... |
938 |
data = tmp_data; |
1da177e4c Linux-2.6.12-rc2 |
939 |
} |
0b8f18e35 cifs: convert cif... |
940 |
|
b8f7442bc CIFS: refactor ci... |
941 942 943 944 945 946 |
/* * 2. Convert it to internal cifs metadata (fattr) */ switch (rc) { case 0: |
2e4564b31 smb3: add support... |
947 948 949 950 951 952 953 954 955 956 957 958 959 960 |
/* * If the file is a reparse point, it is more complicated * since we have to check if its reparse tag matches a known * special file type e.g. symlink or fifo or char etc. */ if ((le32_to_cpu(data->Attributes) & ATTR_REPARSE) && server->ops->query_reparse_tag) { rc = server->ops->query_reparse_tag(xid, tcon, cifs_sb, full_path, &reparse_tag); cifs_dbg(FYI, "reparse tag 0x%x ", reparse_tag); } cifs_all_info_to_fattr(&fattr, data, sb, adjust_tz, is_reparse_point, reparse_tag); |
b8f7442bc CIFS: refactor ci... |
961 962 963 |
break; case -EREMOTE: /* DFS link, no metadata available on this server */ |
0b8f18e35 cifs: convert cif... |
964 |
cifs_create_dfs_fattr(&fattr, sb); |
b9a3260f2 [CIFS] Enable DFS... |
965 |
rc = 0; |
b8f7442bc CIFS: refactor ci... |
966 967 |
break; case -EACCES: |
3b7960cac cifs: fallback to... |
968 |
/* |
b8f7442bc CIFS: refactor ci... |
969 970 971 972 973 974 |
* perm errors, try again with backup flags if possible * * For SMB2 and later the backup intent flag * is already sent if needed on open and there * is no path based FindFirst operation to use * to retry with |
3b7960cac cifs: fallback to... |
975 |
*/ |
b8f7442bc CIFS: refactor ci... |
976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 |
if (backup_cred(cifs_sb) && is_smb1_server(server)) { /* for easier reading */ FILE_DIRECTORY_INFO *fdi; SEARCH_ID_FULL_DIR_INFO *si; rc = cifs_backup_query_path_info(xid, tcon, sb, full_path, &smb1_backup_rsp_buf, &data); if (rc) goto out; fdi = (FILE_DIRECTORY_INFO *)data; si = (SEARCH_ID_FULL_DIR_INFO *)data; cifs_dir_info_to_fattr(&fattr, fdi, cifs_sb); fattr.cf_uniqueid = le64_to_cpu(si->UniqueId); /* uniqueid set, skip get inum step */ goto handle_mnt_opt; } else { /* nothing we can do, bail out */ goto out; |
3b7960cac cifs: fallback to... |
998 |
} |
b8f7442bc CIFS: refactor ci... |
999 1000 1001 1002 1003 1004 |
break; default: cifs_dbg(FYI, "%s: unhandled err rc %d ", __func__, rc); goto out; } |
c052e2b42 cifs: obtain file... |
1005 |
|
b8f7442bc CIFS: refactor ci... |
1006 1007 1008 1009 1010 |
/* * 3. Get or update inode number (fattr.cf_uniqueid) */ cifs_set_fattr_ino(xid, tcon, sb, inode, full_path, data, &fattr); |
1da177e4c Linux-2.6.12-rc2 |
1011 |
|
0b8f18e35 cifs: convert cif... |
1012 |
/* |
b8f7442bc CIFS: refactor ci... |
1013 |
* 4. Tweak fattr based on mount options |
0b8f18e35 cifs: convert cif... |
1014 |
*/ |
b9a3260f2 [CIFS] Enable DFS... |
1015 |
|
b8f7442bc CIFS: refactor ci... |
1016 |
handle_mnt_opt: |
0b8f18e35 cifs: convert cif... |
1017 1018 1019 1020 1021 |
/* query for SFU type info if supported and needed */ if (fattr.cf_cifsattrs & ATTR_SYSTEM && cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { tmprc = cifs_sfu_type(&fattr, full_path, cifs_sb, xid); if (tmprc) |
f96637be0 [CIFS] cifs: Rena... |
1022 1023 |
cifs_dbg(FYI, "cifs_sfu_type failed: %d ", tmprc); |
b9a3260f2 [CIFS] Enable DFS... |
1024 |
} |
1da177e4c Linux-2.6.12-rc2 |
1025 |
|
b9a3260f2 [CIFS] Enable DFS... |
1026 |
/* fill in 0777 bits from ACL */ |
e2f8fbfb8 cifs: get mode bi... |
1027 1028 1029 |
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID) { rc = cifs_acl_to_fattr(cifs_sb, &fattr, *inode, true, full_path, fid); |
01ec372ce cifs: fix DFS mou... |
1030 1031 |
if (rc == -EREMOTE) rc = 0; |
e2f8fbfb8 cifs: get mode bi... |
1032 1033 1034 |
if (rc) { cifs_dbg(FYI, "%s: Get mode from SID failed. rc=%d ", |
b8f7442bc CIFS: refactor ci... |
1035 1036 |
__func__, rc); goto out; |
e2f8fbfb8 cifs: get mode bi... |
1037 1038 1039 |
} } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { rc = cifs_acl_to_fattr(cifs_sb, &fattr, *inode, false, |
68464b88c CIFS: fix a white... |
1040 |
full_path, fid); |
01ec372ce cifs: fix DFS mou... |
1041 1042 |
if (rc == -EREMOTE) rc = 0; |
68464b88c CIFS: fix a white... |
1043 |
if (rc) { |
f96637be0 [CIFS] cifs: Rena... |
1044 1045 1046 |
cifs_dbg(FYI, "%s: Getting ACL failed with error: %d ", __func__, rc); |
b8f7442bc CIFS: refactor ci... |
1047 |
goto out; |
78415d2d3 cifs: Misc. clean... |
1048 |
} |
b9a3260f2 [CIFS] Enable DFS... |
1049 |
} |
b9a3260f2 [CIFS] Enable DFS... |
1050 |
|
0b8f18e35 cifs: convert cif... |
1051 1052 1053 |
/* fill in remaining high mode bits e.g. SUID, VTX */ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) cifs_sfu_mode(&fattr, full_path, cifs_sb, xid); |
b9a3260f2 [CIFS] Enable DFS... |
1054 |
|
1b12b9c15 cifs: use Minshal... |
1055 1056 |
/* check for Minshall+French symlinks */ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) { |
cb084b1a9 cifs: Rename MF s... |
1057 1058 |
tmprc = check_mf_symlink(xid, tcon, cifs_sb, &fattr, full_path); |
1b12b9c15 cifs: use Minshal... |
1059 |
if (tmprc) |
cb084b1a9 cifs: Rename MF s... |
1060 1061 |
cifs_dbg(FYI, "check_mf_symlink: %d ", tmprc); |
1b12b9c15 cifs: use Minshal... |
1062 |
} |
b8f7442bc CIFS: refactor ci... |
1063 1064 1065 |
/* * 5. Update inode with final fattr data */ |
1208ef1f7 CIFS: Move query ... |
1066 1067 1068 |
if (!*inode) { *inode = cifs_iget(sb, &fattr); if (!*inode) |
0b8f18e35 cifs: convert cif... |
1069 1070 |
rc = -ENOMEM; } else { |
7196ac113 Fix to check Uniq... |
1071 |
/* we already have inode, update it */ |
a108471b5 cifs: Check uniqu... |
1072 1073 1074 |
/* if uniqueid is different, return error */ if (unlikely(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM && CIFS_I(*inode)->uniqueid != fattr.cf_uniqueid)) { |
c82e5ac7f CIFS: Force reval... |
1075 |
CIFS_I(*inode)->time = 0; /* force reval */ |
a108471b5 cifs: Check uniqu... |
1076 |
rc = -ESTALE; |
b8f7442bc CIFS: refactor ci... |
1077 |
goto out; |
a108471b5 cifs: Check uniqu... |
1078 |
} |
7196ac113 Fix to check Uniq... |
1079 |
/* if filetype is different, return error */ |
4d66952a2 cifs: have cifs_f... |
1080 |
rc = cifs_fattr_to_inode(*inode, &fattr); |
0b8f18e35 cifs: convert cif... |
1081 |
} |
b8f7442bc CIFS: refactor ci... |
1082 1083 |
out: cifs_buf_release(smb1_backup_rsp_buf); |
7ffec3724 cifs: add refcoun... |
1084 |
cifs_put_tlink(tlink); |
b8f7442bc CIFS: refactor ci... |
1085 |
kfree(tmp_data); |
1da177e4c Linux-2.6.12-rc2 |
1086 1087 |
return rc; } |
6a5f6592a SMB311: Add suppo... |
1088 1089 1090 1091 1092 1093 |
int smb311_posix_get_inode_info(struct inode **inode, const char *full_path, struct super_block *sb, unsigned int xid) { struct cifs_tcon *tcon; |
6a5f6592a SMB311: Add suppo... |
1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 |
struct tcon_link *tlink; struct cifs_sb_info *cifs_sb = CIFS_SB(sb); bool adjust_tz = false; struct cifs_fattr fattr = {0}; bool symlink = false; struct smb311_posix_qinfo *data = NULL; int rc = 0; int tmprc = 0; tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) return PTR_ERR(tlink); tcon = tlink_tcon(tlink); |
6a5f6592a SMB311: Add suppo... |
1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 |
/* * 1. Fetch file metadata */ if (is_inode_cache_good(*inode)) { cifs_dbg(FYI, "No need to revalidate cached inode sizes "); goto out; } data = kmalloc(sizeof(struct smb311_posix_qinfo), GFP_KERNEL); if (!data) { rc = -ENOMEM; goto out; } rc = smb311_posix_query_path_info(xid, tcon, cifs_sb, full_path, data, &adjust_tz, &symlink); /* * 2. Convert it to internal cifs metadata (fattr) */ switch (rc) { case 0: smb311_posix_info_to_fattr(&fattr, data, sb, adjust_tz, symlink); break; case -EREMOTE: /* DFS link, no metadata available on this server */ cifs_create_dfs_fattr(&fattr, sb); rc = 0; break; case -EACCES: /* * For SMB2 and later the backup intent flag * is already sent if needed on open and there * is no path based FindFirst operation to use * to retry with so nothing we can do, bail out */ goto out; default: cifs_dbg(FYI, "%s: unhandled err rc %d ", __func__, rc); goto out; } /* |
a7a519a49 smb3: Add debug m... |
1156 |
* 3. Tweak fattr based on mount options |
6a5f6592a SMB311: Add suppo... |
1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 |
*/ /* check for Minshall+French symlinks */ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) { tmprc = check_mf_symlink(xid, tcon, cifs_sb, &fattr, full_path); if (tmprc) cifs_dbg(FYI, "check_mf_symlink: %d ", tmprc); } /* |
a7a519a49 smb3: Add debug m... |
1169 |
* 4. Update inode with final fattr data |
6a5f6592a SMB311: Add suppo... |
1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 |
*/ if (!*inode) { *inode = cifs_iget(sb, &fattr); if (!*inode) rc = -ENOMEM; } else { /* we already have inode, update it */ /* if uniqueid is different, return error */ if (unlikely(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM && CIFS_I(*inode)->uniqueid != fattr.cf_uniqueid)) { CIFS_I(*inode)->time = 0; /* force reval */ rc = -ESTALE; goto out; } /* if filetype is different, return error */ |
4d66952a2 cifs: have cifs_f... |
1188 |
rc = cifs_fattr_to_inode(*inode, &fattr); |
6a5f6592a SMB311: Add suppo... |
1189 1190 1191 1192 1193 1194 |
} out: cifs_put_tlink(tlink); kfree(data); return rc; } |
7f8ed420f [CIFS] CIFS suppo... |
1195 1196 1197 |
static const struct inode_operations cifs_ipc_inode_ops = { .lookup = cifs_lookup, }; |
cc0bad755 cifs: add new cif... |
1198 1199 1200 1201 |
static int cifs_find_inode(struct inode *inode, void *opaque) { struct cifs_fattr *fattr = (struct cifs_fattr *) opaque; |
f30b9c118 cifs: don't allow... |
1202 |
/* don't match inode with different uniqueid */ |
cc0bad755 cifs: add new cif... |
1203 1204 |
if (CIFS_I(inode)->uniqueid != fattr->cf_uniqueid) return 0; |
20054bd65 cifs: use Creatio... |
1205 1206 1207 |
/* use createtime like an i_generation field */ if (CIFS_I(inode)->createtime != fattr->cf_createtime) return 0; |
f30b9c118 cifs: don't allow... |
1208 |
/* don't match inode of different type */ |
6e3e2c436 new helper: inode... |
1209 |
if (inode_wrong_type(inode, fattr->cf_mode)) |
f30b9c118 cifs: don't allow... |
1210 |
return 0; |
5acfec250 cifs: reduce fals... |
1211 |
/* if it's not a directory or has no dentries, then flag it */ |
b3d9b7a3c vfs: switch i_den... |
1212 |
if (S_ISDIR(inode->i_mode) && !hlist_empty(&inode->i_dentry)) |
3d6943803 cifs: guard again... |
1213 |
fattr->cf_flags |= CIFS_FATTR_INO_COLLISION; |
3d6943803 cifs: guard again... |
1214 |
|
cc0bad755 cifs: add new cif... |
1215 1216 1217 1218 1219 1220 1221 1222 1223 |
return 1; } static int cifs_init_inode(struct inode *inode, void *opaque) { struct cifs_fattr *fattr = (struct cifs_fattr *) opaque; CIFS_I(inode)->uniqueid = fattr->cf_uniqueid; |
20054bd65 cifs: use Creatio... |
1224 |
CIFS_I(inode)->createtime = fattr->cf_createtime; |
cc0bad755 cifs: add new cif... |
1225 1226 |
return 0; } |
5acfec250 cifs: reduce fals... |
1227 1228 1229 1230 1231 1232 1233 1234 1235 |
/* * walk dentry list for an inode and report whether it has aliases that * are hashed. We use this to determine if a directory inode can actually * be used. */ static bool inode_has_hashed_dentries(struct inode *inode) { struct dentry *dentry; |
873feea09 fs: dcache per-in... |
1236 |
spin_lock(&inode->i_lock); |
946e51f2b move d_rcu from o... |
1237 |
hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) { |
5acfec250 cifs: reduce fals... |
1238 |
if (!d_unhashed(dentry) || IS_ROOT(dentry)) { |
873feea09 fs: dcache per-in... |
1239 |
spin_unlock(&inode->i_lock); |
5acfec250 cifs: reduce fals... |
1240 1241 1242 |
return true; } } |
873feea09 fs: dcache per-in... |
1243 |
spin_unlock(&inode->i_lock); |
5acfec250 cifs: reduce fals... |
1244 1245 |
return false; } |
cc0bad755 cifs: add new cif... |
1246 1247 1248 1249 1250 1251 |
/* Given fattrs, get a corresponding inode */ struct inode * cifs_iget(struct super_block *sb, struct cifs_fattr *fattr) { unsigned long hash; struct inode *inode; |
3d6943803 cifs: guard again... |
1252 |
retry_iget5_locked: |
f96637be0 [CIFS] cifs: Rena... |
1253 1254 |
cifs_dbg(FYI, "looking for uniqueid=%llu ", fattr->cf_uniqueid); |
cc0bad755 cifs: add new cif... |
1255 1256 1257 1258 1259 |
/* hash down to 32-bits on 32-bit arch */ hash = cifs_uniqueid_to_ino_t(fattr->cf_uniqueid); inode = iget5_locked(sb, hash, cifs_find_inode, cifs_init_inode, fattr); |
cc0bad755 cifs: add new cif... |
1260 |
if (inode) { |
5acfec250 cifs: reduce fals... |
1261 |
/* was there a potentially problematic inode collision? */ |
3d6943803 cifs: guard again... |
1262 |
if (fattr->cf_flags & CIFS_FATTR_INO_COLLISION) { |
3d6943803 cifs: guard again... |
1263 |
fattr->cf_flags &= ~CIFS_FATTR_INO_COLLISION; |
5acfec250 cifs: reduce fals... |
1264 1265 1266 1267 1268 1269 1270 |
if (inode_has_hashed_dentries(inode)) { cifs_autodisable_serverino(CIFS_SB(sb)); iput(inode); fattr->cf_uniqueid = iunique(sb, ROOT_I); goto retry_iget5_locked; } |
3d6943803 cifs: guard again... |
1271 |
} |
4d66952a2 cifs: have cifs_f... |
1272 |
/* can't fail - see cifs_find_inode() */ |
cc0bad755 cifs: add new cif... |
1273 |
cifs_fattr_to_inode(inode, fattr); |
1751e8a6c Rename superblock... |
1274 |
if (sb->s_flags & SB_NOATIME) |
cc0bad755 cifs: add new cif... |
1275 1276 1277 |
inode->i_flags |= S_NOATIME | S_NOCMTIME; if (inode->i_state & I_NEW) { inode->i_ino = hash; |
0ccd48025 [CIFS] Missing ifdef |
1278 |
#ifdef CONFIG_CIFS_FSCACHE |
9451a9a52 cifs: define inod... |
1279 1280 |
/* initialize per-inode cache cookie pointer */ CIFS_I(inode)->fscache = NULL; |
0ccd48025 [CIFS] Missing ifdef |
1281 |
#endif |
cc0bad755 cifs: add new cif... |
1282 1283 1284 1285 1286 1287 |
unlock_new_inode(inode); } } return inode; } |
1da177e4c Linux-2.6.12-rc2 |
1288 |
/* gets root inode */ |
9b6763e0a cifs: Remove unus... |
1289 |
struct inode *cifs_root_iget(struct super_block *sb) |
1da177e4c Linux-2.6.12-rc2 |
1290 |
{ |
6d5786a34 CIFS: Rename Get/... |
1291 |
unsigned int xid; |
0d424ad0a cifs: add cifs_sb... |
1292 |
struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
cc0bad755 cifs: add new cif... |
1293 |
struct inode *inode = NULL; |
ce634ab28 iget: stop CIFS f... |
1294 |
long rc; |
96daf2b09 [CIFS] Rename thr... |
1295 |
struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); |
a6b5058fa fs/cifs: make sha... |
1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 |
char *path = NULL; int len; if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) && cifs_sb->prepath) { len = strlen(cifs_sb->prepath); path = kzalloc(len + 2 /* leading sep + null */, GFP_KERNEL); if (path == NULL) return ERR_PTR(-ENOMEM); path[0] = '/'; memcpy(path+1, cifs_sb->prepath, len); } else { path = kstrdup("", GFP_KERNEL); if (path == NULL) return ERR_PTR(-ENOMEM); } |
ce634ab28 iget: stop CIFS f... |
1312 |
|
6d5786a34 CIFS: Rename Get/... |
1313 |
xid = get_xid(); |
b5b374eab Workaround Mac se... |
1314 |
if (tcon->unix_ext) { |
a6b5058fa fs/cifs: make sha... |
1315 |
rc = cifs_get_inode_info_unix(&inode, path, sb, xid); |
b5b374eab Workaround Mac se... |
1316 1317 1318 |
/* some servers mistakenly claim POSIX support */ if (rc != -EOPNOTSUPP) goto iget_no_retry; |
a0a3036b8 cifs: Standardize... |
1319 1320 |
cifs_dbg(VFS, "server does not support POSIX extensions "); |
b5b374eab Workaround Mac se... |
1321 1322 |
tcon->unix_ext = false; } |
a6b5058fa fs/cifs: make sha... |
1323 |
convert_delimiter(path, CIFS_DIR_SEP(cifs_sb)); |
d313852d7 smb311: add suppo... |
1324 1325 1326 1327 |
if (tcon->posix_extensions) rc = smb311_posix_get_inode_info(&inode, path, sb, xid); else rc = cifs_get_inode_info(&inode, path, NULL, sb, xid, NULL); |
0b8f18e35 cifs: convert cif... |
1328 |
|
b5b374eab Workaround Mac se... |
1329 |
iget_no_retry: |
a7851ce73 cifs: fix another... |
1330 1331 1332 1333 |
if (!inode) { inode = ERR_PTR(rc); goto out; } |
cc0bad755 cifs: add new cif... |
1334 |
|
0ccd48025 [CIFS] Missing ifdef |
1335 |
#ifdef CONFIG_CIFS_FSCACHE |
d03382ce9 cifs: define supe... |
1336 |
/* populate tcon->resource_id */ |
0d424ad0a cifs: add cifs_sb... |
1337 |
tcon->resource_id = CIFS_I(inode)->uniqueid; |
0ccd48025 [CIFS] Missing ifdef |
1338 |
#endif |
d03382ce9 cifs: define supe... |
1339 |
|
b327a717e CIFS: make IPC a ... |
1340 |
if (rc && tcon->pipe) { |
f96637be0 [CIFS] cifs: Rena... |
1341 1342 |
cifs_dbg(FYI, "ipc connection - fake read inode "); |
b7ca69289 CIFS: Protect i_n... |
1343 |
spin_lock(&inode->i_lock); |
7f8ed420f [CIFS] CIFS suppo... |
1344 |
inode->i_mode |= S_IFDIR; |
bfe868486 filesystems: add ... |
1345 |
set_nlink(inode, 2); |
7f8ed420f [CIFS] CIFS suppo... |
1346 1347 |
inode->i_op = &cifs_ipc_inode_ops; inode->i_fop = &simple_dir_operations; |
8401e9367 cifs: remove [gu]... |
1348 1349 |
inode->i_uid = cifs_sb->ctx->linux_uid; inode->i_gid = cifs_sb->ctx->linux_gid; |
b7ca69289 CIFS: Protect i_n... |
1350 |
spin_unlock(&inode->i_lock); |
ad661334b [CIFS] mount of I... |
1351 |
} else if (rc) { |
ce634ab28 iget: stop CIFS f... |
1352 |
iget_failed(inode); |
a7851ce73 cifs: fix another... |
1353 |
inode = ERR_PTR(rc); |
7f8ed420f [CIFS] CIFS suppo... |
1354 |
} |
a7851ce73 cifs: fix another... |
1355 |
out: |
a6b5058fa fs/cifs: make sha... |
1356 |
kfree(path); |
31cd106bb fs: cifs: Replace... |
1357 |
free_xid(xid); |
ce634ab28 iget: stop CIFS f... |
1358 |
return inode; |
1da177e4c Linux-2.6.12-rc2 |
1359 |
} |
ed6875e0d CIFS: Move unlink... |
1360 |
int |
6d5786a34 CIFS: Rename Get/... |
1361 |
cifs_set_file_info(struct inode *inode, struct iattr *attrs, unsigned int xid, |
f6f1f1790 cifs: constify pa... |
1362 |
const char *full_path, __u32 dosattr) |
388e57b27 [CIFS] use common... |
1363 |
{ |
388e57b27 [CIFS] use common... |
1364 |
bool set_time = false; |
388e57b27 [CIFS] use common... |
1365 |
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
6bdf6dbd6 CIFS: Move set_fi... |
1366 |
struct TCP_Server_Info *server; |
388e57b27 [CIFS] use common... |
1367 |
FILE_BASIC_INFO info_buf; |
1adcb7109 [CIFS] add extra ... |
1368 1369 |
if (attrs == NULL) return -EINVAL; |
6bdf6dbd6 CIFS: Move set_fi... |
1370 1371 1372 |
server = cifs_sb_master_tcon(cifs_sb)->ses->server; if (!server->ops->set_file_info) return -ENOSYS; |
fd09b7d3b smb3: Do not send... |
1373 |
info_buf.Pad = 0; |
388e57b27 [CIFS] use common... |
1374 1375 1376 |
if (attrs->ia_valid & ATTR_ATIME) { set_time = true; info_buf.LastAccessTime = |
95390201e cifs: use timespe... |
1377 |
cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_atime)); |
388e57b27 [CIFS] use common... |
1378 1379 1380 1381 1382 1383 |
} else info_buf.LastAccessTime = 0; if (attrs->ia_valid & ATTR_MTIME) { set_time = true; info_buf.LastWriteTime = |
95390201e cifs: use timespe... |
1384 |
cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_mtime)); |
388e57b27 [CIFS] use common... |
1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 |
} else info_buf.LastWriteTime = 0; /* * Samba throws this field away, but windows may actually use it. * Do not set ctime unless other time stamps are changed explicitly * (i.e. by utimes()) since we would then have a mix of client and * server times. */ if (set_time && (attrs->ia_valid & ATTR_CTIME)) { |
f96637be0 [CIFS] cifs: Rena... |
1395 1396 |
cifs_dbg(FYI, "CIFS - CTIME changed "); |
388e57b27 [CIFS] use common... |
1397 |
info_buf.ChangeTime = |
95390201e cifs: use timespe... |
1398 |
cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_ctime)); |
388e57b27 [CIFS] use common... |
1399 1400 1401 1402 1403 |
} else info_buf.ChangeTime = 0; info_buf.CreationTime = 0; /* don't change */ info_buf.Attributes = cpu_to_le32(dosattr); |
6bdf6dbd6 CIFS: Move set_fi... |
1404 |
return server->ops->set_file_info(inode, full_path, &info_buf, xid); |
388e57b27 [CIFS] use common... |
1405 |
} |
a12a1ac7a cifs: move rename... |
1406 |
/* |
ed6875e0d CIFS: Move unlink... |
1407 |
* Open the given file (if it isn't already), set the DELETE_ON_CLOSE bit |
a12a1ac7a cifs: move rename... |
1408 1409 1410 |
* and rename it to a random name that hopefully won't conflict with * anything else. */ |
ed6875e0d CIFS: Move unlink... |
1411 1412 1413 |
int cifs_rename_pending_delete(const char *full_path, struct dentry *dentry, const unsigned int xid) |
a12a1ac7a cifs: move rename... |
1414 1415 1416 |
{ int oplock = 0; int rc; |
d81b8a40e CIFS: Cleanup cif... |
1417 1418 |
struct cifs_fid fid; struct cifs_open_parms oparms; |
2b0143b5c VFS: normal files... |
1419 |
struct inode *inode = d_inode(dentry); |
a12a1ac7a cifs: move rename... |
1420 1421 |
struct cifsInodeInfo *cifsInode = CIFS_I(inode); struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
7ffec3724 cifs: add refcoun... |
1422 |
struct tcon_link *tlink; |
96daf2b09 [CIFS] Rename thr... |
1423 |
struct cifs_tcon *tcon; |
3270958b7 [CIFS] undo chang... |
1424 1425 |
__u32 dosattr, origattr; FILE_BASIC_INFO *info_buf = NULL; |
a12a1ac7a cifs: move rename... |
1426 |
|
7ffec3724 cifs: add refcoun... |
1427 1428 1429 1430 |
tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) return PTR_ERR(tlink); tcon = tlink_tcon(tlink); |
c483a9841 cifs: Check serve... |
1431 1432 1433 1434 1435 1436 1437 1438 |
/* * We cannot rename the file if the server doesn't support * CAP_INFOLEVEL_PASSTHRU */ if (!(tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)) { rc = -EBUSY; goto out; } |
d81b8a40e CIFS: Cleanup cif... |
1439 1440 1441 |
oparms.tcon = tcon; oparms.cifs_sb = cifs_sb; oparms.desired_access = DELETE | FILE_WRITE_ATTRIBUTES; |
0f060936e SMB3: Backup inte... |
1442 |
oparms.create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR); |
d81b8a40e CIFS: Cleanup cif... |
1443 1444 1445 1446 1447 1448 |
oparms.disposition = FILE_OPEN; oparms.path = full_path; oparms.fid = &fid; oparms.reconnect = false; rc = CIFS_open(xid, &oparms, &oplock, NULL); |
a12a1ac7a cifs: move rename... |
1449 1450 |
if (rc != 0) goto out; |
3270958b7 [CIFS] undo chang... |
1451 1452 1453 1454 1455 |
origattr = cifsInode->cifsAttrs; if (origattr == 0) origattr |= ATTR_NORMAL; dosattr = origattr & ~ATTR_READONLY; |
a12a1ac7a cifs: move rename... |
1456 1457 1458 |
if (dosattr == 0) dosattr |= ATTR_NORMAL; dosattr |= ATTR_HIDDEN; |
3270958b7 [CIFS] undo chang... |
1459 1460 1461 1462 1463 1464 1465 1466 |
/* set ATTR_HIDDEN and clear ATTR_READONLY, but only if needed */ if (dosattr != origattr) { info_buf = kzalloc(sizeof(*info_buf), GFP_KERNEL); if (info_buf == NULL) { rc = -ENOMEM; goto out_close; } info_buf->Attributes = cpu_to_le32(dosattr); |
d81b8a40e CIFS: Cleanup cif... |
1467 |
rc = CIFSSMBSetFileInfo(xid, tcon, info_buf, fid.netfid, |
3270958b7 [CIFS] undo chang... |
1468 1469 1470 |
current->tgid); /* although we would like to mark the file hidden if that fails we will still try to rename it */ |
72d282dc5 cifs: Fix bug whe... |
1471 |
if (!rc) |
3270958b7 [CIFS] undo chang... |
1472 1473 1474 |
cifsInode->cifsAttrs = dosattr; else dosattr = origattr; /* since not able to change them */ |
a12a1ac7a cifs: move rename... |
1475 |
} |
a12a1ac7a cifs: move rename... |
1476 |
|
dd1db2ded cifs: don't use C... |
1477 |
/* rename the file */ |
d81b8a40e CIFS: Cleanup cif... |
1478 1479 |
rc = CIFSSMBRenameOpenFile(xid, tcon, fid.netfid, NULL, cifs_sb->local_nls, |
2baa26825 Remap reserved po... |
1480 |
cifs_remap(cifs_sb)); |
3270958b7 [CIFS] undo chang... |
1481 |
if (rc != 0) { |
47c78f4a7 cifs: map NT_STAT... |
1482 |
rc = -EBUSY; |
3270958b7 [CIFS] undo chang... |
1483 1484 |
goto undo_setattr; } |
6d22f0989 cifs: add functio... |
1485 |
|
3270958b7 [CIFS] undo chang... |
1486 |
/* try to set DELETE_ON_CLOSE */ |
aff8d5ca7 cifs: convert boo... |
1487 |
if (!test_bit(CIFS_INO_DELETE_PENDING, &cifsInode->flags)) { |
d81b8a40e CIFS: Cleanup cif... |
1488 |
rc = CIFSSMBSetFileDisposition(xid, tcon, true, fid.netfid, |
3270958b7 [CIFS] undo chang... |
1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 |
current->tgid); /* * some samba versions return -ENOENT when we try to set the * file disposition here. Likely a samba bug, but work around * it for now. This means that some cifsXXX files may hang * around after they shouldn't. * * BB: remove this hack after more servers have the fix */ if (rc == -ENOENT) rc = 0; else if (rc != 0) { |
47c78f4a7 cifs: map NT_STAT... |
1501 |
rc = -EBUSY; |
3270958b7 [CIFS] undo chang... |
1502 1503 |
goto undo_rename; } |
aff8d5ca7 cifs: convert boo... |
1504 |
set_bit(CIFS_INO_DELETE_PENDING, &cifsInode->flags); |
3270958b7 [CIFS] undo chang... |
1505 |
} |
7ce86d5a9 cifs: work around... |
1506 |
|
a12a1ac7a cifs: move rename... |
1507 |
out_close: |
d81b8a40e CIFS: Cleanup cif... |
1508 |
CIFSSMBClose(xid, tcon, fid.netfid); |
a12a1ac7a cifs: move rename... |
1509 |
out: |
3270958b7 [CIFS] undo chang... |
1510 |
kfree(info_buf); |
7ffec3724 cifs: add refcoun... |
1511 |
cifs_put_tlink(tlink); |
a12a1ac7a cifs: move rename... |
1512 |
return rc; |
3270958b7 [CIFS] undo chang... |
1513 1514 1515 1516 1517 1518 1519 |
/* * reset everything back to the original state. Don't bother * dealing with errors here since we can't do anything about * them anyway. */ undo_rename: |
d81b8a40e CIFS: Cleanup cif... |
1520 |
CIFSSMBRenameOpenFile(xid, tcon, fid.netfid, dentry->d_name.name, |
2baa26825 Remap reserved po... |
1521 |
cifs_sb->local_nls, cifs_remap(cifs_sb)); |
3270958b7 [CIFS] undo chang... |
1522 1523 1524 |
undo_setattr: if (dosattr != origattr) { info_buf->Attributes = cpu_to_le32(origattr); |
d81b8a40e CIFS: Cleanup cif... |
1525 |
if (!CIFSSMBSetFileInfo(xid, tcon, info_buf, fid.netfid, |
3270958b7 [CIFS] undo chang... |
1526 1527 1528 1529 1530 |
current->tgid)) cifsInode->cifsAttrs = origattr; } goto out_close; |
a12a1ac7a cifs: move rename... |
1531 |
} |
b7ca69289 CIFS: Protect i_n... |
1532 1533 1534 1535 1536 1537 1538 1539 1540 |
/* copied from fs/nfs/dir.c with small changes */ static void cifs_drop_nlink(struct inode *inode) { spin_lock(&inode->i_lock); if (inode->i_nlink > 0) drop_nlink(inode); spin_unlock(&inode->i_lock); } |
ff6945279 [CIFS] Make cifs_... |
1541 1542 |
/* |
2b0143b5c VFS: normal files... |
1543 |
* If d_inode(dentry) is null (usually meaning the cached dentry |
ff6945279 [CIFS] Make cifs_... |
1544 |
* is a negative dentry) then we would attempt a standard SMB delete, but |
413d61008 cifs: fix spellin... |
1545 1546 |
* if that fails we can not attempt the fall back mechanisms on EACCES * but will return the EACCES to the caller. Note that the VFS does not call |
ff6945279 [CIFS] Make cifs_... |
1547 1548 |
* unlink on negative dentries currently. */ |
5f0319a79 cifs: clean up va... |
1549 |
int cifs_unlink(struct inode *dir, struct dentry *dentry) |
1da177e4c Linux-2.6.12-rc2 |
1550 1551 |
{ int rc = 0; |
6d5786a34 CIFS: Rename Get/... |
1552 |
unsigned int xid; |
f6a9bc336 cifs: allocate bu... |
1553 1554 |
const char *full_path; void *page; |
2b0143b5c VFS: normal files... |
1555 |
struct inode *inode = d_inode(dentry); |
ff6945279 [CIFS] Make cifs_... |
1556 |
struct cifsInodeInfo *cifs_inode; |
5f0319a79 cifs: clean up va... |
1557 1558 |
struct super_block *sb = dir->i_sb; struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
7ffec3724 cifs: add refcoun... |
1559 |
struct tcon_link *tlink; |
96daf2b09 [CIFS] Rename thr... |
1560 |
struct cifs_tcon *tcon; |
ed6875e0d CIFS: Move unlink... |
1561 |
struct TCP_Server_Info *server; |
6050247d8 [CIFS] clean up ... |
1562 1563 |
struct iattr *attrs = NULL; __u32 dosattr = 0, origattr = 0; |
1da177e4c Linux-2.6.12-rc2 |
1564 |
|
f96637be0 [CIFS] cifs: Rena... |
1565 1566 |
cifs_dbg(FYI, "cifs_unlink, dir=0x%p, dentry=0x%p ", dir, dentry); |
1da177e4c Linux-2.6.12-rc2 |
1567 |
|
087f757b0 cifs: add shutdow... |
1568 1569 |
if (unlikely(cifs_forced_shutdown(cifs_sb))) return -EIO; |
7ffec3724 cifs: add refcoun... |
1570 1571 1572 1573 |
tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) return PTR_ERR(tlink); tcon = tlink_tcon(tlink); |
ed6875e0d CIFS: Move unlink... |
1574 |
server = tcon->ses->server; |
7ffec3724 cifs: add refcoun... |
1575 |
|
6d5786a34 CIFS: Rename Get/... |
1576 |
xid = get_xid(); |
f6a9bc336 cifs: allocate bu... |
1577 |
page = alloc_dentry_path(); |
1da177e4c Linux-2.6.12-rc2 |
1578 |
|
82e9367c4 smb3: Add new par... |
1579 1580 1581 1582 |
if (tcon->nodelete) { rc = -EACCES; goto unlink_out; } |
5f0319a79 cifs: clean up va... |
1583 1584 |
/* Unlink can be called from rename so we can not take the * sb->s_vfs_rename_mutex here */ |
f6a9bc336 cifs: allocate bu... |
1585 1586 1587 |
full_path = build_path_from_dentry(dentry, page); if (IS_ERR(full_path)) { rc = PTR_ERR(full_path); |
7ffec3724 cifs: add refcoun... |
1588 |
goto unlink_out; |
1da177e4c Linux-2.6.12-rc2 |
1589 |
} |
2d785a50a [CIFS] Add suppor... |
1590 |
|
e3fc06568 cifs: Deferred cl... |
1591 |
cifs_close_deferred_file_under_dentry(tcon, full_path); |
29e20f9c6 CIFS: Make CAP_* ... |
1592 1593 |
if (cap_unix(tcon->ses) && (CIFS_UNIX_POSIX_PATH_OPS_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability))) { |
5f0319a79 cifs: clean up va... |
1594 |
rc = CIFSPOSIXDelFile(xid, tcon, full_path, |
2d785a50a [CIFS] Add suppor... |
1595 |
SMB_POSIX_UNLINK_FILE_TARGET, cifs_sb->local_nls, |
2baa26825 Remap reserved po... |
1596 |
cifs_remap(cifs_sb)); |
f96637be0 [CIFS] cifs: Rena... |
1597 1598 |
cifs_dbg(FYI, "posix del rc %d ", rc); |
2d785a50a [CIFS] Add suppor... |
1599 1600 1601 |
if ((rc == 0) || (rc == -ENOENT)) goto psx_del_no_retry; } |
1da177e4c Linux-2.6.12-rc2 |
1602 |
|
6050247d8 [CIFS] clean up ... |
1603 |
retry_std_delete: |
ed6875e0d CIFS: Move unlink... |
1604 1605 1606 1607 1608 1609 |
if (!server->ops->unlink) { rc = -ENOSYS; goto psx_del_no_retry; } rc = server->ops->unlink(xid, tcon, full_path, cifs_sb); |
6050247d8 [CIFS] clean up ... |
1610 |
|
2d785a50a [CIFS] Add suppor... |
1611 |
psx_del_no_retry: |
1da177e4c Linux-2.6.12-rc2 |
1612 |
if (!rc) { |
5f0319a79 cifs: clean up va... |
1613 |
if (inode) |
b7ca69289 CIFS: Protect i_n... |
1614 |
cifs_drop_nlink(inode); |
1da177e4c Linux-2.6.12-rc2 |
1615 |
} else if (rc == -ENOENT) { |
5f0319a79 cifs: clean up va... |
1616 |
d_drop(dentry); |
47c78f4a7 cifs: map NT_STAT... |
1617 |
} else if (rc == -EBUSY) { |
ed6875e0d CIFS: Move unlink... |
1618 1619 1620 1621 1622 1623 |
if (server->ops->rename_pending_delete) { rc = server->ops->rename_pending_delete(full_path, dentry, xid); if (rc == 0) cifs_drop_nlink(inode); } |
ff6945279 [CIFS] Make cifs_... |
1624 |
} else if ((rc == -EACCES) && (dosattr == 0) && inode) { |
388e57b27 [CIFS] use common... |
1625 1626 1627 1628 |
attrs = kzalloc(sizeof(*attrs), GFP_KERNEL); if (attrs == NULL) { rc = -ENOMEM; goto out_reval; |
1da177e4c Linux-2.6.12-rc2 |
1629 |
} |
388e57b27 [CIFS] use common... |
1630 1631 |
/* try to reset dos attributes */ |
ff6945279 [CIFS] Make cifs_... |
1632 1633 |
cifs_inode = CIFS_I(inode); origattr = cifs_inode->cifsAttrs; |
6050247d8 [CIFS] clean up ... |
1634 1635 1636 |
if (origattr == 0) origattr |= ATTR_NORMAL; dosattr = origattr & ~ATTR_READONLY; |
388e57b27 [CIFS] use common... |
1637 1638 1639 1640 1641 |
if (dosattr == 0) dosattr |= ATTR_NORMAL; dosattr |= ATTR_HIDDEN; rc = cifs_set_file_info(inode, attrs, xid, full_path, dosattr); |
388e57b27 [CIFS] use common... |
1642 1643 |
if (rc != 0) goto out_reval; |
6050247d8 [CIFS] clean up ... |
1644 1645 |
goto retry_std_delete; |
1da177e4c Linux-2.6.12-rc2 |
1646 |
} |
6050247d8 [CIFS] clean up ... |
1647 1648 1649 1650 |
/* undo the setattr if we errored out and it's needed */ if (rc != 0 && dosattr != 0) cifs_set_file_info(inode, attrs, xid, full_path, origattr); |
388e57b27 [CIFS] use common... |
1651 |
out_reval: |
4523cc304 [CIFS] UID/GID ov... |
1652 |
if (inode) { |
ff6945279 [CIFS] Make cifs_... |
1653 1654 |
cifs_inode = CIFS_I(inode); cifs_inode->time = 0; /* will force revalidate to get info |
5f0319a79 cifs: clean up va... |
1655 |
when needed */ |
e37fea58f fs: cifs: replace... |
1656 |
inode->i_ctime = current_time(inode); |
06bcfedd0 [CIFS] Fix typo i... |
1657 |
} |
e37fea58f fs: cifs: replace... |
1658 |
dir->i_ctime = dir->i_mtime = current_time(dir); |
ff6945279 [CIFS] Make cifs_... |
1659 |
cifs_inode = CIFS_I(dir); |
6050247d8 [CIFS] clean up ... |
1660 |
CIFS_I(dir)->time = 0; /* force revalidate of dir as well */ |
7ffec3724 cifs: add refcoun... |
1661 |
unlink_out: |
f6a9bc336 cifs: allocate bu... |
1662 |
free_dentry_path(page); |
6050247d8 [CIFS] clean up ... |
1663 |
kfree(attrs); |
6d5786a34 CIFS: Rename Get/... |
1664 |
free_xid(xid); |
7ffec3724 cifs: add refcoun... |
1665 |
cifs_put_tlink(tlink); |
1da177e4c Linux-2.6.12-rc2 |
1666 1667 |
return rc; } |
ff691e969 CIFS: Simplify ci... |
1668 |
static int |
101b92d95 cifs: cleanups fo... |
1669 |
cifs_mkdir_qinfo(struct inode *parent, struct dentry *dentry, umode_t mode, |
ff691e969 CIFS: Simplify ci... |
1670 1671 1672 1673 |
const char *full_path, struct cifs_sb_info *cifs_sb, struct cifs_tcon *tcon, const unsigned int xid) { int rc = 0; |
101b92d95 cifs: cleanups fo... |
1674 |
struct inode *inode = NULL; |
ff691e969 CIFS: Simplify ci... |
1675 |
|
d313852d7 smb311: add suppo... |
1676 1677 1678 |
if (tcon->posix_extensions) rc = smb311_posix_get_inode_info(&inode, full_path, parent->i_sb, xid); else if (tcon->unix_ext) |
101b92d95 cifs: cleanups fo... |
1679 |
rc = cifs_get_inode_info_unix(&inode, full_path, parent->i_sb, |
ff691e969 CIFS: Simplify ci... |
1680 1681 |
xid); else |
101b92d95 cifs: cleanups fo... |
1682 1683 |
rc = cifs_get_inode_info(&inode, full_path, NULL, parent->i_sb, xid, NULL); |
ff691e969 CIFS: Simplify ci... |
1684 1685 |
if (rc) return rc; |
3bcb39b08 cifs: have ->mkdi... |
1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 |
if (!S_ISDIR(inode->i_mode)) { /* * mkdir succeeded, but another client has managed to remove the * sucker and replace it with non-directory. Return success, * but don't leave the child in dcache. */ iput(inode); d_drop(dentry); return 0; } |
ff691e969 CIFS: Simplify ci... |
1696 1697 |
/* * setting nlink not necessary except in cases where we failed to get it |
101b92d95 cifs: cleanups fo... |
1698 1699 |
* from the server or was set bogus. Also, since this is a brand new * inode, no need to grab the i_lock before setting the i_nlink. |
ff691e969 CIFS: Simplify ci... |
1700 |
*/ |
101b92d95 cifs: cleanups fo... |
1701 1702 |
if (inode->i_nlink < 2) set_nlink(inode, 2); |
ff691e969 CIFS: Simplify ci... |
1703 1704 |
mode &= ~current_umask(); /* must turn on setgid bit if parent dir has it */ |
101b92d95 cifs: cleanups fo... |
1705 |
if (parent->i_mode & S_ISGID) |
ff691e969 CIFS: Simplify ci... |
1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 |
mode |= S_ISGID; if (tcon->unix_ext) { struct cifs_unix_set_info_args args = { .mode = mode, .ctime = NO_CHANGE_64, .atime = NO_CHANGE_64, .mtime = NO_CHANGE_64, .device = 0, }; if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { |
49418b2c2 cifs: Modify stru... |
1717 |
args.uid = current_fsuid(); |
101b92d95 cifs: cleanups fo... |
1718 |
if (parent->i_mode & S_ISGID) |
49418b2c2 cifs: Modify stru... |
1719 |
args.gid = parent->i_gid; |
ff691e969 CIFS: Simplify ci... |
1720 |
else |
49418b2c2 cifs: Modify stru... |
1721 |
args.gid = current_fsgid(); |
ff691e969 CIFS: Simplify ci... |
1722 |
} else { |
49418b2c2 cifs: Modify stru... |
1723 1724 |
args.uid = INVALID_UID; /* no change */ args.gid = INVALID_GID; /* no change */ |
ff691e969 CIFS: Simplify ci... |
1725 1726 1727 |
} CIFSSMBUnixSetPathInfo(xid, tcon, full_path, &args, cifs_sb->local_nls, |
2baa26825 Remap reserved po... |
1728 |
cifs_remap(cifs_sb)); |
ff691e969 CIFS: Simplify ci... |
1729 |
} else { |
f436720e9 CIFS: Separate pr... |
1730 |
struct TCP_Server_Info *server = tcon->ses->server; |
ff691e969 CIFS: Simplify ci... |
1731 |
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) && |
f436720e9 CIFS: Separate pr... |
1732 |
(mode & S_IWUGO) == 0 && server->ops->mkdir_setinfo) |
101b92d95 cifs: cleanups fo... |
1733 |
server->ops->mkdir_setinfo(inode, full_path, cifs_sb, |
f436720e9 CIFS: Separate pr... |
1734 |
tcon, xid); |
101b92d95 cifs: cleanups fo... |
1735 1736 1737 1738 1739 1740 1741 1742 1743 |
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) inode->i_mode = (mode | S_IFDIR); if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { inode->i_uid = current_fsuid(); if (inode->i_mode & S_ISGID) inode->i_gid = parent->i_gid; else inode->i_gid = current_fsgid(); |
ff691e969 CIFS: Simplify ci... |
1744 1745 |
} } |
101b92d95 cifs: cleanups fo... |
1746 |
d_instantiate(dentry, inode); |
3bcb39b08 cifs: have ->mkdi... |
1747 |
return 0; |
ff691e969 CIFS: Simplify ci... |
1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 |
} static int cifs_posix_mkdir(struct inode *inode, struct dentry *dentry, umode_t mode, const char *full_path, struct cifs_sb_info *cifs_sb, struct cifs_tcon *tcon, const unsigned int xid) { int rc = 0; u32 oplock = 0; FILE_UNIX_BASIC_INFO *info = NULL; struct inode *newinode = NULL; struct cifs_fattr fattr; info = kzalloc(sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL); if (info == NULL) { rc = -ENOMEM; goto posix_mkdir_out; } mode &= ~current_umask(); rc = CIFSPOSIXCreate(xid, tcon, SMB_O_DIRECTORY | SMB_O_CREAT, mode, NULL /* netfid */, info, &oplock, full_path, |
2baa26825 Remap reserved po... |
1770 |
cifs_sb->local_nls, cifs_remap(cifs_sb)); |
ff691e969 CIFS: Simplify ci... |
1771 1772 1773 |
if (rc == -EOPNOTSUPP) goto posix_mkdir_out; else if (rc) { |
f96637be0 [CIFS] cifs: Rena... |
1774 1775 |
cifs_dbg(FYI, "posix mkdir returned 0x%x ", rc); |
ff691e969 CIFS: Simplify ci... |
1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 |
d_drop(dentry); goto posix_mkdir_out; } if (info->Type == cpu_to_le32(-1)) /* no return info, go query for it */ goto posix_mkdir_get_info; /* * BB check (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID ) to see if * need to set uid/gid. */ cifs_unix_basic_to_fattr(&fattr, info, cifs_sb); cifs_fill_uniqueid(inode->i_sb, &fattr); newinode = cifs_iget(inode->i_sb, &fattr); if (!newinode) goto posix_mkdir_get_info; d_instantiate(dentry, newinode); #ifdef CONFIG_CIFS_DEBUG2 |
35c265e00 cifs: switch to u... |
1797 1798 1799 |
cifs_dbg(FYI, "instantiated dentry %p %pd to inode %p ", dentry, dentry, newinode); |
ff691e969 CIFS: Simplify ci... |
1800 1801 |
if (newinode->i_nlink != 2) |
f96637be0 [CIFS] cifs: Rena... |
1802 1803 1804 |
cifs_dbg(FYI, "unexpected number of links %d ", newinode->i_nlink); |
ff691e969 CIFS: Simplify ci... |
1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 |
#endif posix_mkdir_out: kfree(info); return rc; posix_mkdir_get_info: rc = cifs_mkdir_qinfo(inode, dentry, mode, full_path, cifs_sb, tcon, xid); goto posix_mkdir_out; } |
549c72977 fs: make helpers ... |
1815 1816 |
int cifs_mkdir(struct user_namespace *mnt_userns, struct inode *inode, struct dentry *direntry, umode_t mode) |
1da177e4c Linux-2.6.12-rc2 |
1817 |
{ |
ff691e969 CIFS: Simplify ci... |
1818 |
int rc = 0; |
6d5786a34 CIFS: Rename Get/... |
1819 |
unsigned int xid; |
1da177e4c Linux-2.6.12-rc2 |
1820 |
struct cifs_sb_info *cifs_sb; |
7ffec3724 cifs: add refcoun... |
1821 |
struct tcon_link *tlink; |
29e20f9c6 CIFS: Make CAP_* ... |
1822 |
struct cifs_tcon *tcon; |
f436720e9 CIFS: Separate pr... |
1823 |
struct TCP_Server_Info *server; |
8e33cf20c cifs: make build_... |
1824 |
const char *full_path; |
f6a9bc336 cifs: allocate bu... |
1825 |
void *page; |
1da177e4c Linux-2.6.12-rc2 |
1826 |
|
f52aa79df cifs: Fix mode ou... |
1827 1828 |
cifs_dbg(FYI, "In cifs_mkdir, mode = %04ho inode = 0x%p ", |
f96637be0 [CIFS] cifs: Rena... |
1829 |
mode, inode); |
1da177e4c Linux-2.6.12-rc2 |
1830 |
|
1da177e4c Linux-2.6.12-rc2 |
1831 |
cifs_sb = CIFS_SB(inode->i_sb); |
087f757b0 cifs: add shutdow... |
1832 1833 |
if (unlikely(cifs_forced_shutdown(cifs_sb))) return -EIO; |
7ffec3724 cifs: add refcoun... |
1834 1835 1836 |
tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) return PTR_ERR(tlink); |
29e20f9c6 CIFS: Make CAP_* ... |
1837 |
tcon = tlink_tcon(tlink); |
7ffec3724 cifs: add refcoun... |
1838 |
|
6d5786a34 CIFS: Rename Get/... |
1839 |
xid = get_xid(); |
1da177e4c Linux-2.6.12-rc2 |
1840 |
|
f6a9bc336 cifs: allocate bu... |
1841 1842 1843 1844 |
page = alloc_dentry_path(); full_path = build_path_from_dentry(direntry, page); if (IS_ERR(full_path)) { rc = PTR_ERR(full_path); |
7ffec3724 cifs: add refcoun... |
1845 |
goto mkdir_out; |
1da177e4c Linux-2.6.12-rc2 |
1846 |
} |
50c2f7538 [CIFS] whitespace... |
1847 |
|
bea851b8b smb3: Fix mode on... |
1848 |
server = tcon->ses->server; |
bea851b8b smb3: Fix mode on... |
1849 1850 1851 1852 1853 1854 |
if ((server->ops->posix_mkdir) && (tcon->posix_extensions)) { rc = server->ops->posix_mkdir(xid, inode, mode, tcon, full_path, cifs_sb); d_drop(direntry); /* for time being always refresh inode info */ goto mkdir_out; } |
bea851b8b smb3: Fix mode on... |
1855 |
|
29e20f9c6 CIFS: Make CAP_* ... |
1856 1857 |
if (cap_unix(tcon->ses) && (CIFS_UNIX_POSIX_PATH_OPS_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability))) { |
ff691e969 CIFS: Simplify ci... |
1858 1859 1860 |
rc = cifs_posix_mkdir(inode, direntry, mode, full_path, cifs_sb, tcon, xid); if (rc != -EOPNOTSUPP) |
2dd29d313 [CIFS] New CIFS P... |
1861 |
goto mkdir_out; |
fb8c4b14d [CIFS] whitespace... |
1862 |
} |
ff691e969 CIFS: Simplify ci... |
1863 |
|
f436720e9 CIFS: Separate pr... |
1864 1865 1866 1867 |
if (!server->ops->mkdir) { rc = -ENOSYS; goto mkdir_out; } |
1da177e4c Linux-2.6.12-rc2 |
1868 |
/* BB add setting the equivalent of mode via CreateX w/ACLs */ |
c3ca78e21 smb3: pass mode b... |
1869 |
rc = server->ops->mkdir(xid, inode, mode, tcon, full_path, cifs_sb); |
1da177e4c Linux-2.6.12-rc2 |
1870 |
if (rc) { |
f96637be0 [CIFS] cifs: Rena... |
1871 1872 |
cifs_dbg(FYI, "cifs_mkdir returned 0x%x ", rc); |
1da177e4c Linux-2.6.12-rc2 |
1873 |
d_drop(direntry); |
ff691e969 CIFS: Simplify ci... |
1874 |
goto mkdir_out; |
1da177e4c Linux-2.6.12-rc2 |
1875 |
} |
ff691e969 CIFS: Simplify ci... |
1876 |
|
c3ca78e21 smb3: pass mode b... |
1877 |
/* TODO: skip this for smb2/smb3 */ |
ff691e969 CIFS: Simplify ci... |
1878 1879 |
rc = cifs_mkdir_qinfo(inode, direntry, mode, full_path, cifs_sb, tcon, xid); |
fb8c4b14d [CIFS] whitespace... |
1880 |
mkdir_out: |
6de2ce423 CIFS: Fix mkdir/r... |
1881 1882 1883 1884 1885 |
/* * Force revalidate to get parent dir info when needed since cached * attributes are invalid now. */ CIFS_I(inode)->time = 0; |
f6a9bc336 cifs: allocate bu... |
1886 |
free_dentry_path(page); |
6d5786a34 CIFS: Rename Get/... |
1887 |
free_xid(xid); |
7ffec3724 cifs: add refcoun... |
1888 |
cifs_put_tlink(tlink); |
1da177e4c Linux-2.6.12-rc2 |
1889 1890 1891 1892 1893 1894 |
return rc; } int cifs_rmdir(struct inode *inode, struct dentry *direntry) { int rc = 0; |
6d5786a34 CIFS: Rename Get/... |
1895 |
unsigned int xid; |
1da177e4c Linux-2.6.12-rc2 |
1896 |
struct cifs_sb_info *cifs_sb; |
7ffec3724 cifs: add refcoun... |
1897 |
struct tcon_link *tlink; |
f958ca5d8 CIFS: Move rmdir ... |
1898 1899 |
struct cifs_tcon *tcon; struct TCP_Server_Info *server; |
f6a9bc336 cifs: allocate bu... |
1900 1901 |
const char *full_path; void *page = alloc_dentry_path(); |
1da177e4c Linux-2.6.12-rc2 |
1902 |
struct cifsInodeInfo *cifsInode; |
f96637be0 [CIFS] cifs: Rena... |
1903 1904 |
cifs_dbg(FYI, "cifs_rmdir, inode = 0x%p ", inode); |
1da177e4c Linux-2.6.12-rc2 |
1905 |
|
6d5786a34 CIFS: Rename Get/... |
1906 |
xid = get_xid(); |
1da177e4c Linux-2.6.12-rc2 |
1907 |
|
f6a9bc336 cifs: allocate bu... |
1908 1909 1910 |
full_path = build_path_from_dentry(direntry, page); if (IS_ERR(full_path)) { rc = PTR_ERR(full_path); |
7ffec3724 cifs: add refcoun... |
1911 |
goto rmdir_exit; |
1da177e4c Linux-2.6.12-rc2 |
1912 |
} |
7ffec3724 cifs: add refcoun... |
1913 |
cifs_sb = CIFS_SB(inode->i_sb); |
087f757b0 cifs: add shutdow... |
1914 1915 1916 1917 |
if (unlikely(cifs_forced_shutdown(cifs_sb))) { rc = -EIO; goto rmdir_exit; } |
7ffec3724 cifs: add refcoun... |
1918 1919 1920 1921 1922 |
tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) { rc = PTR_ERR(tlink); goto rmdir_exit; } |
f958ca5d8 CIFS: Move rmdir ... |
1923 1924 1925 1926 1927 1928 1929 1930 |
tcon = tlink_tcon(tlink); server = tcon->ses->server; if (!server->ops->rmdir) { rc = -ENOSYS; cifs_put_tlink(tlink); goto rmdir_exit; } |
7ffec3724 cifs: add refcoun... |
1931 |
|
82e9367c4 smb3: Add new par... |
1932 1933 1934 1935 1936 |
if (tcon->nodelete) { rc = -EACCES; cifs_put_tlink(tlink); goto rmdir_exit; } |
f958ca5d8 CIFS: Move rmdir ... |
1937 |
rc = server->ops->rmdir(xid, tcon, full_path, cifs_sb); |
7ffec3724 cifs: add refcoun... |
1938 |
cifs_put_tlink(tlink); |
1da177e4c Linux-2.6.12-rc2 |
1939 1940 |
if (!rc) { |
2b0143b5c VFS: normal files... |
1941 1942 1943 1944 |
spin_lock(&d_inode(direntry)->i_lock); i_size_write(d_inode(direntry), 0); clear_nlink(d_inode(direntry)); spin_unlock(&d_inode(direntry)->i_lock); |
1da177e4c Linux-2.6.12-rc2 |
1945 |
} |
2b0143b5c VFS: normal files... |
1946 |
cifsInode = CIFS_I(d_inode(direntry)); |
6de2ce423 CIFS: Fix mkdir/r... |
1947 1948 |
/* force revalidate to go get info when needed */ cifsInode->time = 0; |
42c245447 [CIFS] revalidate... |
1949 1950 |
cifsInode = CIFS_I(inode); |
6de2ce423 CIFS: Fix mkdir/r... |
1951 1952 1953 1954 1955 |
/* * Force revalidate to get parent dir info when needed since cached * attributes are invalid now. */ cifsInode->time = 0; |
42c245447 [CIFS] revalidate... |
1956 |
|
2b0143b5c VFS: normal files... |
1957 |
d_inode(direntry)->i_ctime = inode->i_ctime = inode->i_mtime = |
e37fea58f fs: cifs: replace... |
1958 |
current_time(inode); |
1da177e4c Linux-2.6.12-rc2 |
1959 |
|
7ffec3724 cifs: add refcoun... |
1960 |
rmdir_exit: |
f6a9bc336 cifs: allocate bu... |
1961 |
free_dentry_path(page); |
6d5786a34 CIFS: Rename Get/... |
1962 |
free_xid(xid); |
1da177e4c Linux-2.6.12-rc2 |
1963 1964 |
return rc; } |
ee2fd967f [CIFS] fix busy-... |
1965 |
static int |
8ceb98437 CIFS: Move rename... |
1966 1967 1968 |
cifs_do_rename(const unsigned int xid, struct dentry *from_dentry, const char *from_path, struct dentry *to_dentry, const char *to_path) |
ee2fd967f [CIFS] fix busy-... |
1969 1970 |
{ struct cifs_sb_info *cifs_sb = CIFS_SB(from_dentry->d_sb); |
7ffec3724 cifs: add refcoun... |
1971 |
struct tcon_link *tlink; |
8ceb98437 CIFS: Move rename... |
1972 1973 |
struct cifs_tcon *tcon; struct TCP_Server_Info *server; |
d81b8a40e CIFS: Cleanup cif... |
1974 1975 |
struct cifs_fid fid; struct cifs_open_parms oparms; |
ee2fd967f [CIFS] fix busy-... |
1976 |
int oplock, rc; |
7ffec3724 cifs: add refcoun... |
1977 1978 1979 |
tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) return PTR_ERR(tlink); |
8ceb98437 CIFS: Move rename... |
1980 1981 1982 1983 1984 |
tcon = tlink_tcon(tlink); server = tcon->ses->server; if (!server->ops->rename) return -ENOSYS; |
7ffec3724 cifs: add refcoun... |
1985 |
|
ee2fd967f [CIFS] fix busy-... |
1986 |
/* try path-based rename first */ |
8ceb98437 CIFS: Move rename... |
1987 |
rc = server->ops->rename(xid, tcon, from_path, to_path, cifs_sb); |
ee2fd967f [CIFS] fix busy-... |
1988 1989 |
/* |
8ceb98437 CIFS: Move rename... |
1990 1991 |
* Don't bother with rename by filehandle unless file is busy and * source. Note that cross directory moves do not work with |
ee2fd967f [CIFS] fix busy-... |
1992 1993 |
* rename by filehandle to various Windows servers. */ |
47c78f4a7 cifs: map NT_STAT... |
1994 |
if (rc == 0 || rc != -EBUSY) |
7ffec3724 cifs: add refcoun... |
1995 |
goto do_rename_exit; |
ee2fd967f [CIFS] fix busy-... |
1996 |
|
652727bbe cifs: do not atte... |
1997 1998 1999 |
/* Don't fall back to using SMB on SMB 2+ mount */ if (server->vals->protocol_id != 0) goto do_rename_exit; |
ed0e3ace5 cifs: don't attem... |
2000 2001 |
/* open-file renames don't work across directories */ if (to_dentry->d_parent != from_dentry->d_parent) |
7ffec3724 cifs: add refcoun... |
2002 |
goto do_rename_exit; |
ed0e3ace5 cifs: don't attem... |
2003 |
|
d81b8a40e CIFS: Cleanup cif... |
2004 2005 |
oparms.tcon = tcon; oparms.cifs_sb = cifs_sb; |
ee2fd967f [CIFS] fix busy-... |
2006 |
/* open the file to be renamed -- we need DELETE perms */ |
d81b8a40e CIFS: Cleanup cif... |
2007 |
oparms.desired_access = DELETE; |
0f060936e SMB3: Backup inte... |
2008 |
oparms.create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR); |
d81b8a40e CIFS: Cleanup cif... |
2009 2010 2011 2012 2013 2014 |
oparms.disposition = FILE_OPEN; oparms.path = from_path; oparms.fid = &fid; oparms.reconnect = false; rc = CIFS_open(xid, &oparms, &oplock, NULL); |
ee2fd967f [CIFS] fix busy-... |
2015 |
if (rc == 0) { |
d81b8a40e CIFS: Cleanup cif... |
2016 |
rc = CIFSSMBRenameOpenFile(xid, tcon, fid.netfid, |
ee2fd967f [CIFS] fix busy-... |
2017 |
(const char *) to_dentry->d_name.name, |
2baa26825 Remap reserved po... |
2018 |
cifs_sb->local_nls, cifs_remap(cifs_sb)); |
d81b8a40e CIFS: Cleanup cif... |
2019 |
CIFSSMBClose(xid, tcon, fid.netfid); |
ee2fd967f [CIFS] fix busy-... |
2020 |
} |
7ffec3724 cifs: add refcoun... |
2021 |
do_rename_exit: |
c7e9f78f7 cifs: do d_move i... |
2022 2023 |
if (rc == 0) d_move(from_dentry, to_dentry); |
7ffec3724 cifs: add refcoun... |
2024 |
cifs_put_tlink(tlink); |
ee2fd967f [CIFS] fix busy-... |
2025 2026 |
return rc; } |
8ceb98437 CIFS: Move rename... |
2027 |
int |
549c72977 fs: make helpers ... |
2028 2029 2030 |
cifs_rename2(struct user_namespace *mnt_userns, struct inode *source_dir, struct dentry *source_dentry, struct inode *target_dir, struct dentry *target_dentry, unsigned int flags) |
1da177e4c Linux-2.6.12-rc2 |
2031 |
{ |
f6a9bc336 cifs: allocate bu... |
2032 2033 |
const char *from_name, *to_name; void *page1, *page2; |
639e7a913 cifs: eliminate r... |
2034 |
struct cifs_sb_info *cifs_sb; |
7ffec3724 cifs: add refcoun... |
2035 |
struct tcon_link *tlink; |
96daf2b09 [CIFS] Rename thr... |
2036 |
struct cifs_tcon *tcon; |
ee2fd967f [CIFS] fix busy-... |
2037 2038 |
FILE_UNIX_BASIC_INFO *info_buf_source = NULL; FILE_UNIX_BASIC_INFO *info_buf_target; |
6d5786a34 CIFS: Rename Get/... |
2039 2040 |
unsigned int xid; int rc, tmprc; |
41535701d cifs: Handle race... |
2041 |
int retry_count = 0; |
1da177e4c Linux-2.6.12-rc2 |
2042 |
|
7c33d5972 cifs: support REN... |
2043 2044 |
if (flags & ~RENAME_NOREPLACE) return -EINVAL; |
639e7a913 cifs: eliminate r... |
2045 |
cifs_sb = CIFS_SB(source_dir->i_sb); |
087f757b0 cifs: add shutdow... |
2046 2047 |
if (unlikely(cifs_forced_shutdown(cifs_sb))) return -EIO; |
7ffec3724 cifs: add refcoun... |
2048 2049 2050 2051 |
tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) return PTR_ERR(tlink); tcon = tlink_tcon(tlink); |
1da177e4c Linux-2.6.12-rc2 |
2052 |
|
f6a9bc336 cifs: allocate bu... |
2053 2054 |
page1 = alloc_dentry_path(); page2 = alloc_dentry_path(); |
6d5786a34 CIFS: Rename Get/... |
2055 |
xid = get_xid(); |
ee2fd967f [CIFS] fix busy-... |
2056 |
|
f6a9bc336 cifs: allocate bu... |
2057 2058 2059 |
from_name = build_path_from_dentry(source_dentry, page1); if (IS_ERR(from_name)) { rc = PTR_ERR(from_name); |
ee2fd967f [CIFS] fix busy-... |
2060 2061 |
goto cifs_rename_exit; } |
f6a9bc336 cifs: allocate bu... |
2062 2063 2064 |
to_name = build_path_from_dentry(target_dentry, page2); if (IS_ERR(to_name)) { rc = PTR_ERR(to_name); |
1da177e4c Linux-2.6.12-rc2 |
2065 2066 |
goto cifs_rename_exit; } |
e3fc06568 cifs: Deferred cl... |
2067 |
cifs_close_deferred_file_under_dentry(tcon, from_name); |
41535701d cifs: Handle race... |
2068 |
if (d_inode(target_dentry) != NULL) |
e3fc06568 cifs: Deferred cl... |
2069 |
cifs_close_deferred_file_under_dentry(tcon, to_name); |
41535701d cifs: Handle race... |
2070 |
|
8ceb98437 CIFS: Move rename... |
2071 2072 |
rc = cifs_do_rename(xid, source_dentry, from_name, target_dentry, to_name); |
ee2fd967f [CIFS] fix busy-... |
2073 |
|
41535701d cifs: Handle race... |
2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 |
if (rc == -EACCES) { while (retry_count < 3) { cifs_close_all_deferred_files(tcon); rc = cifs_do_rename(xid, source_dentry, from_name, target_dentry, to_name); if (rc != -EACCES) break; retry_count++; } } |
7c33d5972 cifs: support REN... |
2084 2085 2086 2087 2088 |
/* * No-replace is the natural behavior for CIFS, so skip unlink hacks. */ if (flags & RENAME_NOREPLACE) goto cifs_rename_exit; |
14121bdcc cifs: make cifs_r... |
2089 2090 |
if (rc == -EEXIST && tcon->unix_ext) { /* |
8ceb98437 CIFS: Move rename... |
2091 2092 |
* Are src and dst hardlinks of same inode? We can only tell * with unix extensions enabled. |
14121bdcc cifs: make cifs_r... |
2093 2094 |
*/ info_buf_source = |
6da2ec560 treewide: kmalloc... |
2095 |
kmalloc_array(2, sizeof(FILE_UNIX_BASIC_INFO), |
14121bdcc cifs: make cifs_r... |
2096 2097 2098 2099 2100 2101 2102 |
GFP_KERNEL); if (info_buf_source == NULL) { rc = -ENOMEM; goto cifs_rename_exit; } info_buf_target = info_buf_source + 1; |
8ceb98437 CIFS: Move rename... |
2103 2104 2105 |
tmprc = CIFSSMBUnixQPathInfo(xid, tcon, from_name, info_buf_source, cifs_sb->local_nls, |
2baa26825 Remap reserved po... |
2106 |
cifs_remap(cifs_sb)); |
8d281efb6 cifs: fix unlinki... |
2107 |
if (tmprc != 0) |
14121bdcc cifs: make cifs_r... |
2108 |
goto unlink_target; |
ee2fd967f [CIFS] fix busy-... |
2109 |
|
8ceb98437 CIFS: Move rename... |
2110 2111 2112 |
tmprc = CIFSSMBUnixQPathInfo(xid, tcon, to_name, info_buf_target, cifs_sb->local_nls, |
2baa26825 Remap reserved po... |
2113 |
cifs_remap(cifs_sb)); |
14121bdcc cifs: make cifs_r... |
2114 |
|
8d281efb6 cifs: fix unlinki... |
2115 |
if (tmprc == 0 && (info_buf_source->UniqueId == |
ae6884a9d cifs: fix renamin... |
2116 |
info_buf_target->UniqueId)) { |
14121bdcc cifs: make cifs_r... |
2117 |
/* same file, POSIX says that this is a noop */ |
ae6884a9d cifs: fix renamin... |
2118 |
rc = 0; |
14121bdcc cifs: make cifs_r... |
2119 |
goto cifs_rename_exit; |
ae6884a9d cifs: fix renamin... |
2120 |
} |
8ceb98437 CIFS: Move rename... |
2121 2122 2123 2124 2125 |
} /* * else ... BB we could add the same check for Windows by * checking the UniqueId via FILE_INTERNAL_INFO */ |
14121bdcc cifs: make cifs_r... |
2126 |
|
ee2fd967f [CIFS] fix busy-... |
2127 |
unlink_target: |
0e6705182 Revert "cifs: Fix... |
2128 2129 |
/* Try unlinking the target dentry if it's not negative */ if (d_really_is_positive(target_dentry) && (rc == -EACCES || rc == -EEXIST)) { |
a07d32205 CIFS: Fix directo... |
2130 2131 2132 2133 |
if (d_is_dir(target_dentry)) tmprc = cifs_rmdir(target_dir, target_dentry); else tmprc = cifs_unlink(target_dir, target_dentry); |
14121bdcc cifs: make cifs_r... |
2134 2135 |
if (tmprc) goto cifs_rename_exit; |
8ceb98437 CIFS: Move rename... |
2136 2137 |
rc = cifs_do_rename(xid, source_dentry, from_name, target_dentry, to_name); |
1da177e4c Linux-2.6.12-rc2 |
2138 |
} |
b46799a8f CIFS: Fix wrong d... |
2139 2140 2141 2142 |
/* force revalidate to go get info when needed */ CIFS_I(source_dir)->time = CIFS_I(target_dir)->time = 0; source_dir->i_ctime = source_dir->i_mtime = target_dir->i_ctime = |
e37fea58f fs: cifs: replace... |
2143 |
target_dir->i_mtime = current_time(source_dir); |
b46799a8f CIFS: Fix wrong d... |
2144 |
|
1da177e4c Linux-2.6.12-rc2 |
2145 |
cifs_rename_exit: |
ee2fd967f [CIFS] fix busy-... |
2146 |
kfree(info_buf_source); |
f6a9bc336 cifs: allocate bu... |
2147 2148 |
free_dentry_path(page2); free_dentry_path(page1); |
6d5786a34 CIFS: Rename Get/... |
2149 |
free_xid(xid); |
7ffec3724 cifs: add refcoun... |
2150 |
cifs_put_tlink(tlink); |
1da177e4c Linux-2.6.12-rc2 |
2151 2152 |
return rc; } |
df2cf170c cifs: overhaul ci... |
2153 |
static bool |
ed8561fa1 cifs: pass the de... |
2154 |
cifs_dentry_needs_reval(struct dentry *dentry) |
1da177e4c Linux-2.6.12-rc2 |
2155 |
{ |
ed8561fa1 cifs: pass the de... |
2156 |
struct inode *inode = d_inode(dentry); |
df2cf170c cifs: overhaul ci... |
2157 |
struct cifsInodeInfo *cifs_i = CIFS_I(inode); |
6d20e8406 cifs: add attribu... |
2158 |
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
f6d2353a5 cifs: check the t... |
2159 2160 |
struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); struct cached_fid *cfid = NULL; |
1da177e4c Linux-2.6.12-rc2 |
2161 |
|
57c55cd7c cifs: invalidate ... |
2162 2163 |
if (cifs_i->time == 0) return true; |
18cceb6a7 CIFS: Replace cli... |
2164 |
if (CIFS_CACHE_READ(cifs_i)) |
df2cf170c cifs: overhaul ci... |
2165 |
return false; |
1da177e4c Linux-2.6.12-rc2 |
2166 |
|
df2cf170c cifs: overhaul ci... |
2167 2168 |
if (!lookupCacheEnabled) return true; |
1da177e4c Linux-2.6.12-rc2 |
2169 |
|
f6d2353a5 cifs: check the t... |
2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 |
if (!open_cached_dir_by_dentry(tcon, dentry->d_parent, &cfid)) { mutex_lock(&cfid->fid_mutex); if (cfid->time && cifs_i->time > cfid->time) { mutex_unlock(&cfid->fid_mutex); close_cached_dir(cfid); return false; } mutex_unlock(&cfid->fid_mutex); close_cached_dir(cfid); } |
ddaf6d4a9 cifs: convert rev... |
2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 |
/* * depending on inode type, check if attribute caching disabled for * files or directories */ if (S_ISDIR(inode->i_mode)) { if (!cifs_sb->ctx->acdirmax) return true; if (!time_in_range(jiffies, cifs_i->time, cifs_i->time + cifs_sb->ctx->acdirmax)) return true; } else { /* file */ |
578046461 cifs: Add new par... |
2191 |
if (!cifs_sb->ctx->acregmax) |
ddaf6d4a9 cifs: convert rev... |
2192 2193 |
return true; if (!time_in_range(jiffies, cifs_i->time, |
578046461 cifs: Add new par... |
2194 |
cifs_i->time + cifs_sb->ctx->acregmax)) |
ddaf6d4a9 cifs: convert rev... |
2195 2196 |
return true; } |
df2cf170c cifs: overhaul ci... |
2197 |
|
db19272ed cifs: always reva... |
2198 |
/* hardlinked files w/ noserverino get "special" treatment */ |
6d20e8406 cifs: add attribu... |
2199 |
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) && |
db19272ed cifs: always reva... |
2200 2201 |
S_ISREG(inode->i_mode) && inode->i_nlink != 1) return true; |
df2cf170c cifs: overhaul ci... |
2202 2203 |
return false; } |
523fb8c86 cifs: trivial com... |
2204 2205 2206 |
/* * Zap the cache. Called when invalid_mapping flag is set. */ |
6feb9891d CIFS: Simplify in... |
2207 |
int |
df2cf170c cifs: overhaul ci... |
2208 2209 |
cifs_invalidate_mapping(struct inode *inode) { |
6feb9891d CIFS: Simplify in... |
2210 |
int rc = 0; |
df2cf170c cifs: overhaul ci... |
2211 |
|
df2cf170c cifs: overhaul ci... |
2212 |
if (inode->i_mapping && inode->i_mapping->nrpages != 0) { |
257fb1f15 CIFS: Use invalid... |
2213 |
rc = invalidate_inode_pages2(inode->i_mapping); |
4f73c7d34 cifs: fix potenti... |
2214 |
if (rc) |
a0a3036b8 cifs: Standardize... |
2215 2216 |
cifs_dbg(VFS, "%s: Could not invalidate inode %p ", |
f96637be0 [CIFS] cifs: Rena... |
2217 |
__func__, inode); |
df2cf170c cifs: overhaul ci... |
2218 |
} |
257fb1f15 CIFS: Use invalid... |
2219 |
|
9451a9a52 cifs: define inod... |
2220 |
cifs_fscache_reset_inode_cookie(inode); |
6feb9891d CIFS: Simplify in... |
2221 |
return rc; |
df2cf170c cifs: overhaul ci... |
2222 |
} |
4f73c7d34 cifs: fix potenti... |
2223 2224 |
/** * cifs_wait_bit_killable - helper for functions that are sleeping on bit locks |
607dfc79c cifs: remove vari... |
2225 2226 2227 |
* * @key: currently unused * @mode: the task state to sleep in |
4f73c7d34 cifs: fix potenti... |
2228 2229 |
*/ static int |
dfd01f026 sched/wait: Fix t... |
2230 |
cifs_wait_bit_killable(struct wait_bit_key *key, int mode) |
4f73c7d34 cifs: fix potenti... |
2231 |
{ |
4f73c7d34 cifs: fix potenti... |
2232 |
freezable_schedule_unsafe(); |
dfd01f026 sched/wait: Fix t... |
2233 2234 |
if (signal_pending_state(mode, current)) return -ERESTARTSYS; |
4f73c7d34 cifs: fix potenti... |
2235 2236 |
return 0; } |
e284e53fd cifs: new helper ... |
2237 2238 2239 |
int cifs_revalidate_mapping(struct inode *inode) { |
4f73c7d34 cifs: fix potenti... |
2240 2241 |
int rc; unsigned long *flags = &CIFS_I(inode)->flags; |
18d04062f cifs: enable fsca... |
2242 |
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
4f73c7d34 cifs: fix potenti... |
2243 |
|
4e8aea30f smb3: enable swap... |
2244 2245 2246 |
/* swapfiles are not supposed to be shared */ if (IS_SWAPFILE(inode)) return 0; |
743162013 sched: Remove pro... |
2247 2248 |
rc = wait_on_bit_lock_action(flags, CIFS_INO_LOCK, cifs_wait_bit_killable, TASK_KILLABLE); |
4f73c7d34 cifs: fix potenti... |
2249 2250 2251 2252 |
if (rc) return rc; if (test_and_clear_bit(CIFS_INO_INVALID_MAPPING, flags)) { |
18d04062f cifs: enable fsca... |
2253 2254 2255 |
/* for cache=singleclient, do not invalidate */ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RW_CACHE) goto skip_invalidate; |
4f73c7d34 cifs: fix potenti... |
2256 2257 2258 2259 |
rc = cifs_invalidate_mapping(inode); if (rc) set_bit(CIFS_INO_INVALID_MAPPING, flags); } |
18d04062f cifs: enable fsca... |
2260 |
skip_invalidate: |
4f73c7d34 cifs: fix potenti... |
2261 |
clear_bit_unlock(CIFS_INO_LOCK, flags); |
b1cce8032 Merge branch 'for... |
2262 |
smp_mb__after_atomic(); |
4f73c7d34 cifs: fix potenti... |
2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 |
wake_up_bit(flags, CIFS_INO_LOCK); return rc; } int cifs_zap_mapping(struct inode *inode) { set_bit(CIFS_INO_INVALID_MAPPING, &CIFS_I(inode)->flags); return cifs_revalidate_mapping(inode); |
e284e53fd cifs: new helper ... |
2273 |
} |
6feb9891d CIFS: Simplify in... |
2274 |
int cifs_revalidate_file_attr(struct file *filp) |
abab095d1 cifs: add cifs_re... |
2275 2276 |
{ int rc = 0; |
ed8561fa1 cifs: pass the de... |
2277 |
struct dentry *dentry = file_dentry(filp); |
ba00ba64c cifs: make variou... |
2278 |
struct cifsFileInfo *cfile = (struct cifsFileInfo *) filp->private_data; |
abab095d1 cifs: add cifs_re... |
2279 |
|
ed8561fa1 cifs: pass the de... |
2280 |
if (!cifs_dentry_needs_reval(dentry)) |
6feb9891d CIFS: Simplify in... |
2281 |
return rc; |
abab095d1 cifs: add cifs_re... |
2282 |
|
13cfb7334 cifs: have cifsFi... |
2283 |
if (tlink_tcon(cfile->tlink)->unix_ext) |
abab095d1 cifs: add cifs_re... |
2284 2285 2286 |
rc = cifs_get_file_info_unix(filp); else rc = cifs_get_file_info(filp); |
abab095d1 cifs: add cifs_re... |
2287 2288 |
return rc; } |
6feb9891d CIFS: Simplify in... |
2289 |
int cifs_revalidate_dentry_attr(struct dentry *dentry) |
df2cf170c cifs: overhaul ci... |
2290 |
{ |
6d5786a34 CIFS: Rename Get/... |
2291 |
unsigned int xid; |
df2cf170c cifs: overhaul ci... |
2292 |
int rc = 0; |
2b0143b5c VFS: normal files... |
2293 |
struct inode *inode = d_inode(dentry); |
df2cf170c cifs: overhaul ci... |
2294 |
struct super_block *sb = dentry->d_sb; |
f6a9bc336 cifs: allocate bu... |
2295 2296 |
const char *full_path; void *page; |
fc513fac5 cifs: don't leak ... |
2297 |
int count = 0; |
df2cf170c cifs: overhaul ci... |
2298 2299 2300 |
if (inode == NULL) return -ENOENT; |
1da177e4c Linux-2.6.12-rc2 |
2301 |
|
ed8561fa1 cifs: pass the de... |
2302 |
if (!cifs_dentry_needs_reval(dentry)) |
6feb9891d CIFS: Simplify in... |
2303 |
return rc; |
6d5786a34 CIFS: Rename Get/... |
2304 |
xid = get_xid(); |
1da177e4c Linux-2.6.12-rc2 |
2305 |
|
f6a9bc336 cifs: allocate bu... |
2306 2307 2308 2309 |
page = alloc_dentry_path(); full_path = build_path_from_dentry(dentry, page); if (IS_ERR(full_path)) { rc = PTR_ERR(full_path); |
6feb9891d CIFS: Simplify in... |
2310 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
2311 |
} |
f96637be0 [CIFS] cifs: Rena... |
2312 2313 2314 |
cifs_dbg(FYI, "Update attributes: %s inode 0x%p count %d dentry: 0x%p d_time %ld jiffies %ld ", full_path, inode, inode->i_count.counter, |
a00be0e31 cifs: don't use -... |
2315 |
dentry, cifs_get_time(dentry), jiffies); |
1da177e4c Linux-2.6.12-rc2 |
2316 |
|
fc513fac5 cifs: don't leak ... |
2317 |
again: |
6a5f6592a SMB311: Add suppo... |
2318 2319 2320 |
if (cifs_sb_master_tcon(CIFS_SB(sb))->posix_extensions) rc = smb311_posix_get_inode_info(&inode, full_path, sb, xid); else if (cifs_sb_master_tcon(CIFS_SB(sb))->unix_ext) |
df2cf170c cifs: overhaul ci... |
2321 2322 2323 2324 |
rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid); else rc = cifs_get_inode_info(&inode, full_path, NULL, sb, xid, NULL); |
fc513fac5 cifs: don't leak ... |
2325 2326 |
if (rc == -EAGAIN && count++ < 10) goto again; |
6feb9891d CIFS: Simplify in... |
2327 |
out: |
f6a9bc336 cifs: allocate bu... |
2328 |
free_dentry_path(page); |
6d5786a34 CIFS: Rename Get/... |
2329 |
free_xid(xid); |
fc513fac5 cifs: don't leak ... |
2330 |
|
1da177e4c Linux-2.6.12-rc2 |
2331 2332 |
return rc; } |
6feb9891d CIFS: Simplify in... |
2333 2334 2335 |
int cifs_revalidate_file(struct file *filp) { int rc; |
496ad9aa8 new helper: file_... |
2336 |
struct inode *inode = file_inode(filp); |
6feb9891d CIFS: Simplify in... |
2337 2338 2339 2340 |
rc = cifs_revalidate_file_attr(filp); if (rc) return rc; |
e284e53fd cifs: new helper ... |
2341 |
return cifs_revalidate_mapping(inode); |
6feb9891d CIFS: Simplify in... |
2342 2343 2344 2345 2346 2347 |
} /* revalidate a dentry's inode attributes */ int cifs_revalidate_dentry(struct dentry *dentry) { int rc; |
2b0143b5c VFS: normal files... |
2348 |
struct inode *inode = d_inode(dentry); |
6feb9891d CIFS: Simplify in... |
2349 2350 2351 2352 |
rc = cifs_revalidate_dentry_attr(dentry); if (rc) return rc; |
e284e53fd cifs: new helper ... |
2353 |
return cifs_revalidate_mapping(inode); |
6feb9891d CIFS: Simplify in... |
2354 |
} |
549c72977 fs: make helpers ... |
2355 2356 |
int cifs_getattr(struct user_namespace *mnt_userns, const struct path *path, struct kstat *stat, u32 request_mask, unsigned int flags) |
1da177e4c Linux-2.6.12-rc2 |
2357 |
{ |
a528d35e8 statx: Add a syst... |
2358 |
struct dentry *dentry = path->dentry; |
3aa1c8c29 cifs: on multiuse... |
2359 |
struct cifs_sb_info *cifs_sb = CIFS_SB(dentry->d_sb); |
96daf2b09 [CIFS] Rename thr... |
2360 |
struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); |
2b0143b5c VFS: normal files... |
2361 |
struct inode *inode = d_inode(dentry); |
6feb9891d CIFS: Simplify in... |
2362 |
int rc; |
3aa1c8c29 cifs: on multiuse... |
2363 |
|
087f757b0 cifs: add shutdow... |
2364 2365 |
if (unlikely(cifs_forced_shutdown(CIFS_SB(inode->i_sb)))) return -EIO; |
6feb9891d CIFS: Simplify in... |
2366 2367 2368 2369 |
/* * We need to be sure that all dirty pages are written and the server * has actual ctime, mtime and file length. */ |
65af8f016 cifs: fix allocat... |
2370 |
if ((request_mask & (STATX_CTIME | STATX_MTIME | STATX_SIZE | STATX_BLOCKS)) && |
ffdec8d64 cifs: do not igno... |
2371 2372 |
!CIFS_CACHE_READ(CIFS_I(inode)) && inode->i_mapping && inode->i_mapping->nrpages != 0) { |
6feb9891d CIFS: Simplify in... |
2373 |
rc = filemap_fdatawait(inode->i_mapping); |
156ecb2d8 [CIFS] Fix to pro... |
2374 2375 2376 2377 |
if (rc) { mapping_set_error(inode->i_mapping, rc); return rc; } |
6feb9891d CIFS: Simplify in... |
2378 |
} |
1c456013e cifs: on multiuse... |
2379 |
|
ffdec8d64 cifs: do not igno... |
2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 |
if ((flags & AT_STATX_SYNC_TYPE) == AT_STATX_FORCE_SYNC) CIFS_I(inode)->time = 0; /* force revalidate */ /* * If the caller doesn't require syncing, only sync if * necessary (e.g. due to earlier truncate or setattr * invalidating the cached metadata) */ if (((flags & AT_STATX_SYNC_TYPE) != AT_STATX_DONT_SYNC) || (CIFS_I(inode)->time == 0)) { rc = cifs_revalidate_dentry_attr(dentry); if (rc) return rc; } |
6feb9891d CIFS: Simplify in... |
2394 |
|
0d56a4518 stat: handle idma... |
2395 |
generic_fillattr(&init_user_ns, inode, stat); |
522aa3b57 cifs: move [brw]s... |
2396 |
stat->blksize = cifs_sb->ctx->bsize; |
6feb9891d CIFS: Simplify in... |
2397 |
stat->ino = CIFS_I(inode)->uniqueid; |
6e70e26dc SMB3: handle new ... |
2398 2399 2400 |
/* old CIFS Unix Extensions doesn't return create time */ if (CIFS_I(inode)->createtime) { stat->result_mask |= STATX_BTIME; |
95390201e cifs: use timespe... |
2401 2402 |
stat->btime = cifs_NTtimeToUnix(cpu_to_le64(CIFS_I(inode)->createtime)); |
6e70e26dc SMB3: handle new ... |
2403 2404 2405 2406 2407 2408 2409 |
} stat->attributes_mask |= (STATX_ATTR_COMPRESSED | STATX_ATTR_ENCRYPTED); if (CIFS_I(inode)->cifsAttrs & FILE_ATTRIBUTE_COMPRESSED) stat->attributes |= STATX_ATTR_COMPRESSED; if (CIFS_I(inode)->cifsAttrs & FILE_ATTRIBUTE_ENCRYPTED) stat->attributes |= STATX_ATTR_ENCRYPTED; |
6feb9891d CIFS: Simplify in... |
2410 |
/* |
d3d1fce11 cifs: don't overr... |
2411 2412 2413 |
* If on a multiuser mount without unix extensions or cifsacl being * enabled, and the admin hasn't overridden them, set the ownership * to the fsuid/fsgid of the current process. |
6feb9891d CIFS: Simplify in... |
2414 2415 |
*/ if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER) && |
d3d1fce11 cifs: don't overr... |
2416 |
!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) && |
6feb9891d CIFS: Simplify in... |
2417 2418 2419 2420 2421 |
!tcon->unix_ext) { if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)) stat->uid = current_fsuid(); if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)) stat->gid = current_fsgid(); |
5fe14c851 [CIFS] Explicitly... |
2422 |
} |
39946886f cifs: potential u... |
2423 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
2424 |
} |
2f3ebaba1 cifs: add fiemap ... |
2425 2426 2427 2428 2429 2430 2431 2432 2433 |
int cifs_fiemap(struct inode *inode, struct fiemap_extent_info *fei, u64 start, u64 len) { struct cifsInodeInfo *cifs_i = CIFS_I(inode); struct cifs_sb_info *cifs_sb = CIFS_SB(cifs_i->vfs_inode.i_sb); struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); struct TCP_Server_Info *server = tcon->ses->server; struct cifsFileInfo *cfile; int rc; |
087f757b0 cifs: add shutdow... |
2434 2435 |
if (unlikely(cifs_forced_shutdown(cifs_sb))) return -EIO; |
2f3ebaba1 cifs: add fiemap ... |
2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 |
/* * We need to be sure that all dirty pages are written as they * might fill holes on the server. */ if (!CIFS_CACHE_READ(CIFS_I(inode)) && inode->i_mapping && inode->i_mapping->nrpages != 0) { rc = filemap_fdatawait(inode->i_mapping); if (rc) { mapping_set_error(inode->i_mapping, rc); return rc; } } cfile = find_readable_file(cifs_i, false); if (cfile == NULL) return -EINVAL; if (server->ops->fiemap) { rc = server->ops->fiemap(tcon, cfile, fei, start, len); cifsFileInfo_put(cfile); return rc; } cifsFileInfo_put(cfile); return -ENOTSUPP; } |
8bd0d7014 cifs: add support... |
2462 |
int cifs_truncate_page(struct address_space *mapping, loff_t from) |
1da177e4c Linux-2.6.12-rc2 |
2463 |
{ |
09cbfeaf1 mm, fs: get rid o... |
2464 2465 |
pgoff_t index = from >> PAGE_SHIFT; unsigned offset = from & (PAGE_SIZE - 1); |
1da177e4c Linux-2.6.12-rc2 |
2466 |
struct page *page; |
1da177e4c Linux-2.6.12-rc2 |
2467 2468 2469 2470 2471 |
int rc = 0; page = grab_cache_page(mapping, index); if (!page) return -ENOMEM; |
09cbfeaf1 mm, fs: get rid o... |
2472 |
zero_user_segment(page, offset, PAGE_SIZE); |
1da177e4c Linux-2.6.12-rc2 |
2473 |
unlock_page(page); |
09cbfeaf1 mm, fs: get rid o... |
2474 |
put_page(page); |
1da177e4c Linux-2.6.12-rc2 |
2475 2476 |
return rc; } |
8bd0d7014 cifs: add support... |
2477 |
void cifs_setsize(struct inode *inode, loff_t offset) |
3677db10a [CIFS] Fix lockin... |
2478 |
{ |
57c55cd7c cifs: invalidate ... |
2479 |
struct cifsInodeInfo *cifs_i = CIFS_I(inode); |
ba6a46a03 [CIFS] small piec... |
2480 |
spin_lock(&inode->i_lock); |
3677db10a [CIFS] Fix lockin... |
2481 |
i_size_write(inode, offset); |
ba6a46a03 [CIFS] small piec... |
2482 |
spin_unlock(&inode->i_lock); |
1b9474635 cifs: truncate fa... |
2483 |
|
57c55cd7c cifs: invalidate ... |
2484 2485 |
/* Cached inode must be refreshed on truncate */ cifs_i->time = 0; |
7caef2676 truncate: drop 'o... |
2486 |
truncate_pagecache(inode, offset); |
3677db10a [CIFS] Fix lockin... |
2487 |
} |
8efdbde64 [CIFS] break ATTR... |
2488 2489 |
static int cifs_set_file_size(struct inode *inode, struct iattr *attrs, |
f6f1f1790 cifs: constify pa... |
2490 |
unsigned int xid, const char *full_path) |
8efdbde64 [CIFS] break ATTR... |
2491 2492 2493 2494 2495 |
{ int rc; struct cifsFileInfo *open_file; struct cifsInodeInfo *cifsInode = CIFS_I(inode); struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
7ffec3724 cifs: add refcoun... |
2496 |
struct tcon_link *tlink = NULL; |
d14334181 CIFS: Move set_fi... |
2497 2498 |
struct cifs_tcon *tcon = NULL; struct TCP_Server_Info *server; |
8efdbde64 [CIFS] break ATTR... |
2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 |
/* * To avoid spurious oplock breaks from server, in the case of * inodes that we already have open, avoid doing path based * setting of file size if we can do it by handle. * This keeps our caching token (oplock) and avoids timeouts * when the local oplock break takes longer to flush * writebehind data than the SMB timeout for the SetPathInfo * request would allow */ |
86f740f2a cifs: fix rename(... |
2509 |
open_file = find_writable_file(cifsInode, FIND_WR_FSUID_ONLY); |
8efdbde64 [CIFS] break ATTR... |
2510 |
if (open_file) { |
d14334181 CIFS: Move set_fi... |
2511 2512 2513 2514 2515 2516 2517 |
tcon = tlink_tcon(open_file->tlink); server = tcon->ses->server; if (server->ops->set_file_size) rc = server->ops->set_file_size(xid, tcon, open_file, attrs->ia_size, false); else rc = -ENOSYS; |
6ab409b53 cifs: Replace wrt... |
2518 |
cifsFileInfo_put(open_file); |
f96637be0 [CIFS] cifs: Rena... |
2519 2520 |
cifs_dbg(FYI, "SetFSize for attrs rc = %d ", rc); |
8efdbde64 [CIFS] break ATTR... |
2521 2522 |
} else rc = -EINVAL; |
d14334181 CIFS: Move set_fi... |
2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 |
if (!rc) goto set_size_out; if (tcon == NULL) { tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) return PTR_ERR(tlink); tcon = tlink_tcon(tlink); server = tcon->ses->server; } |
ba00ba64c cifs: make variou... |
2533 |
|
d14334181 CIFS: Move set_fi... |
2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 |
/* * Set file size by pathname rather than by handle either because no * valid, writeable file handle for it was found or because there was * an error setting it by handle. */ if (server->ops->set_path_size) rc = server->ops->set_path_size(xid, tcon, full_path, attrs->ia_size, cifs_sb, false); else rc = -ENOSYS; |
f96637be0 [CIFS] cifs: Rena... |
2544 2545 |
cifs_dbg(FYI, "SetEOF by path (setattrs) rc = %d ", rc); |
d14334181 CIFS: Move set_fi... |
2546 |
|
d14334181 CIFS: Move set_fi... |
2547 2548 |
if (tlink) cifs_put_tlink(tlink); |
8efdbde64 [CIFS] break ATTR... |
2549 |
|
d14334181 CIFS: Move set_fi... |
2550 |
set_size_out: |
8efdbde64 [CIFS] break ATTR... |
2551 |
if (rc == 0) { |
fbec9ab95 cifs: vary timeou... |
2552 |
cifsInode->server_eof = attrs->ia_size; |
1b9474635 cifs: truncate fa... |
2553 |
cifs_setsize(inode, attrs->ia_size); |
65af8f016 cifs: fix allocat... |
2554 2555 2556 2557 2558 2559 2560 2561 |
/* * i_blocks is not related to (i_size / i_blksize), but instead * 512 byte (2**9) size is required for calculating num blocks. * Until we can query the server for actual allocation size, * this is best estimate we have for blocks allocated for a file * Number of blocks must be rounded up so size 1 is not 0 blocks */ inode->i_blocks = (512 - 1 + attrs->ia_size) >> 9; |
5618303d8 cifs: update ctim... |
2562 2563 2564 2565 2566 2567 2568 2569 |
/* * The man page of truncate says if the size changed, * then the st_ctime and st_mtime fields for the file * are updated. */ attrs->ia_ctime = attrs->ia_mtime = current_time(inode); attrs->ia_valid |= ATTR_CTIME | ATTR_MTIME; |
8efdbde64 [CIFS] break ATTR... |
2570 2571 2572 2573 2574 |
cifs_truncate_page(inode->i_mapping, inode->i_size); } return rc; } |
3fe5c1dd0 spin off cifs_set... |
2575 2576 2577 2578 |
static int cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs) { int rc; |
6d5786a34 CIFS: Rename Get/... |
2579 |
unsigned int xid; |
f6a9bc336 cifs: allocate bu... |
2580 2581 |
const char *full_path; void *page = alloc_dentry_path(); |
2b0143b5c VFS: normal files... |
2582 |
struct inode *inode = d_inode(direntry); |
3fe5c1dd0 spin off cifs_set... |
2583 2584 |
struct cifsInodeInfo *cifsInode = CIFS_I(inode); struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
7ffec3724 cifs: add refcoun... |
2585 |
struct tcon_link *tlink; |
96daf2b09 [CIFS] Rename thr... |
2586 |
struct cifs_tcon *pTcon; |
3fe5c1dd0 spin off cifs_set... |
2587 |
struct cifs_unix_set_info_args *args = NULL; |
3bbeeb3c9 cifs: add and use... |
2588 |
struct cifsFileInfo *open_file; |
3fe5c1dd0 spin off cifs_set... |
2589 |
|
35c265e00 cifs: switch to u... |
2590 2591 2592 |
cifs_dbg(FYI, "setattr_unix on file %pd attrs->ia_valid=0x%x ", direntry, attrs->ia_valid); |
3fe5c1dd0 spin off cifs_set... |
2593 |
|
6d5786a34 CIFS: Rename Get/... |
2594 |
xid = get_xid(); |
3fe5c1dd0 spin off cifs_set... |
2595 |
|
db78b877f always call inode... |
2596 2597 |
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) attrs->ia_valid |= ATTR_FORCE; |
2f221d6f7 attr: handle idma... |
2598 |
rc = setattr_prepare(&init_user_ns, direntry, attrs); |
db78b877f always call inode... |
2599 2600 |
if (rc < 0) goto out; |
3fe5c1dd0 spin off cifs_set... |
2601 |
|
f6a9bc336 cifs: allocate bu... |
2602 2603 2604 |
full_path = build_path_from_dentry(direntry, page); if (IS_ERR(full_path)) { rc = PTR_ERR(full_path); |
3fe5c1dd0 spin off cifs_set... |
2605 2606 |
goto out; } |
0f4d634c5 cifs: flush data ... |
2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 |
/* * Attempt to flush data before changing attributes. We need to do * this for ATTR_SIZE and ATTR_MTIME for sure, and if we change the * ownership or mode then we may also need to do this. Here, we take * the safe way out and just do the flush on all setattr requests. If * the flush returns error, store it to report later and continue. * * BB: This should be smarter. Why bother flushing pages that * will be truncated anyway? Also, should we error out here if * the flush returns error? */ rc = filemap_write_and_wait(inode->i_mapping); |
9a66396f1 CIFS: Fix error p... |
2619 2620 2621 2622 |
if (is_interrupt_error(rc)) { rc = -ERESTARTSYS; goto out; } |
eb4b756b1 cifs: eliminate c... |
2623 2624 |
mapping_set_error(inode->i_mapping, rc); rc = 0; |
3fe5c1dd0 spin off cifs_set... |
2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 |
if (attrs->ia_valid & ATTR_SIZE) { rc = cifs_set_file_size(inode, attrs, xid, full_path); if (rc != 0) goto out; } /* skip mode change if it's just for clearing setuid/setgid */ if (attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID)) attrs->ia_valid &= ~ATTR_MODE; args = kmalloc(sizeof(*args), GFP_KERNEL); if (args == NULL) { rc = -ENOMEM; goto out; } /* set up the struct */ if (attrs->ia_valid & ATTR_MODE) args->mode = attrs->ia_mode; else args->mode = NO_CHANGE_64; if (attrs->ia_valid & ATTR_UID) args->uid = attrs->ia_uid; else |
49418b2c2 cifs: Modify stru... |
2651 |
args->uid = INVALID_UID; /* no change */ |
3fe5c1dd0 spin off cifs_set... |
2652 2653 2654 2655 |
if (attrs->ia_valid & ATTR_GID) args->gid = attrs->ia_gid; else |
49418b2c2 cifs: Modify stru... |
2656 |
args->gid = INVALID_GID; /* no change */ |
3fe5c1dd0 spin off cifs_set... |
2657 2658 |
if (attrs->ia_valid & ATTR_ATIME) |
95390201e cifs: use timespe... |
2659 |
args->atime = cifs_UnixTimeToNT(attrs->ia_atime); |
3fe5c1dd0 spin off cifs_set... |
2660 2661 2662 2663 |
else args->atime = NO_CHANGE_64; if (attrs->ia_valid & ATTR_MTIME) |
95390201e cifs: use timespe... |
2664 |
args->mtime = cifs_UnixTimeToNT(attrs->ia_mtime); |
3fe5c1dd0 spin off cifs_set... |
2665 2666 2667 2668 |
else args->mtime = NO_CHANGE_64; if (attrs->ia_valid & ATTR_CTIME) |
95390201e cifs: use timespe... |
2669 |
args->ctime = cifs_UnixTimeToNT(attrs->ia_ctime); |
3fe5c1dd0 spin off cifs_set... |
2670 2671 2672 2673 |
else args->ctime = NO_CHANGE_64; args->device = 0; |
86f740f2a cifs: fix rename(... |
2674 |
open_file = find_writable_file(cifsInode, FIND_WR_FSUID_ONLY); |
3bbeeb3c9 cifs: add and use... |
2675 |
if (open_file) { |
4b4de76e3 CIFS: Replace net... |
2676 |
u16 nfid = open_file->fid.netfid; |
3bbeeb3c9 cifs: add and use... |
2677 |
u32 npid = open_file->pid; |
13cfb7334 cifs: have cifsFi... |
2678 |
pTcon = tlink_tcon(open_file->tlink); |
3bbeeb3c9 cifs: add and use... |
2679 |
rc = CIFSSMBUnixSetFileInfo(xid, pTcon, args, nfid, npid); |
6ab409b53 cifs: Replace wrt... |
2680 |
cifsFileInfo_put(open_file); |
3bbeeb3c9 cifs: add and use... |
2681 |
} else { |
7ffec3724 cifs: add refcoun... |
2682 2683 2684 2685 2686 2687 |
tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) { rc = PTR_ERR(tlink); goto out; } pTcon = tlink_tcon(tlink); |
3bbeeb3c9 cifs: add and use... |
2688 |
rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, args, |
01ea95e3b cifs: rename CIFS... |
2689 |
cifs_sb->local_nls, |
bc8ebdc4f Fix that several ... |
2690 |
cifs_remap(cifs_sb)); |
7ffec3724 cifs: add refcoun... |
2691 |
cifs_put_tlink(tlink); |
3bbeeb3c9 cifs: add and use... |
2692 |
} |
3fe5c1dd0 spin off cifs_set... |
2693 |
|
1025774ce remove inode_setattr |
2694 2695 |
if (rc) goto out; |
ccd4bb1be [CIFS] Don't cach... |
2696 |
|
1025774ce remove inode_setattr |
2697 |
if ((attrs->ia_valid & ATTR_SIZE) && |
1b9474635 cifs: truncate fa... |
2698 2699 |
attrs->ia_size != i_size_read(inode)) truncate_setsize(inode, attrs->ia_size); |
1025774ce remove inode_setattr |
2700 |
|
2f221d6f7 attr: handle idma... |
2701 |
setattr_copy(&init_user_ns, inode, attrs); |
1025774ce remove inode_setattr |
2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 |
mark_inode_dirty(inode); /* force revalidate when any of these times are set since some of the fs types (eg ext3, fat) do not have fine enough time granularity to match protocol, and we do not have a a way (yet) to query the server fs's time granularity (and whether it rounds times down). */ if (attrs->ia_valid & (ATTR_MTIME | ATTR_CTIME)) cifsInode->time = 0; |
3fe5c1dd0 spin off cifs_set... |
2712 2713 |
out: kfree(args); |
f6a9bc336 cifs: allocate bu... |
2714 |
free_dentry_path(page); |
6d5786a34 CIFS: Rename Get/... |
2715 |
free_xid(xid); |
3fe5c1dd0 spin off cifs_set... |
2716 2717 |
return rc; } |
0510eeb73 turn cifs_setattr... |
2718 2719 |
static int cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) |
1da177e4c Linux-2.6.12-rc2 |
2720 |
{ |
6d5786a34 CIFS: Rename Get/... |
2721 |
unsigned int xid; |
8abf2775d cifs: Use kuids a... |
2722 2723 |
kuid_t uid = INVALID_UID; kgid_t gid = INVALID_GID; |
2b0143b5c VFS: normal files... |
2724 |
struct inode *inode = d_inode(direntry); |
3fe5c1dd0 spin off cifs_set... |
2725 |
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
3fe5c1dd0 spin off cifs_set... |
2726 |
struct cifsInodeInfo *cifsInode = CIFS_I(inode); |
aa081859b cifs: flush befor... |
2727 2728 |
struct cifsFileInfo *wfile; struct cifs_tcon *tcon; |
f6a9bc336 cifs: allocate bu... |
2729 2730 |
const char *full_path; void *page = alloc_dentry_path(); |
1da177e4c Linux-2.6.12-rc2 |
2731 |
int rc = -EACCES; |
feb3e20ce move file time an... |
2732 |
__u32 dosattr = 0; |
4e1e7fb9e bundle up Unix SE... |
2733 |
__u64 mode = NO_CHANGE_64; |
3fe5c1dd0 spin off cifs_set... |
2734 |
|
6d5786a34 CIFS: Rename Get/... |
2735 |
xid = get_xid(); |
1da177e4c Linux-2.6.12-rc2 |
2736 |
|
63d614a60 cifs: fix typo in... |
2737 2738 |
cifs_dbg(FYI, "setattr on file %pd attrs->ia_valid 0x%x ", |
35c265e00 cifs: switch to u... |
2739 |
direntry, attrs->ia_valid); |
6473a559c [CIFS] Fix missin... |
2740 |
|
db78b877f always call inode... |
2741 2742 |
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) attrs->ia_valid |= ATTR_FORCE; |
2f221d6f7 attr: handle idma... |
2743 |
rc = setattr_prepare(&init_user_ns, direntry, attrs); |
f6a9bc336 cifs: allocate bu... |
2744 2745 |
if (rc < 0) goto cifs_setattr_exit; |
50c2f7538 [CIFS] whitespace... |
2746 |
|
f6a9bc336 cifs: allocate bu... |
2747 2748 2749 2750 |
full_path = build_path_from_dentry(direntry, page); if (IS_ERR(full_path)) { rc = PTR_ERR(full_path); goto cifs_setattr_exit; |
1da177e4c Linux-2.6.12-rc2 |
2751 |
} |
1da177e4c Linux-2.6.12-rc2 |
2752 |
|
0f4d634c5 cifs: flush data ... |
2753 2754 |
/* * Attempt to flush data before changing attributes. We need to do |
cf5371ae4 smb3: fix perform... |
2755 2756 |
* this for ATTR_SIZE and ATTR_MTIME. If the flush of the data * returns error, store it to report later and continue. |
0f4d634c5 cifs: flush data ... |
2757 2758 2759 |
* * BB: This should be smarter. Why bother flushing pages that * will be truncated anyway? Also, should we error out here if |
cf5371ae4 smb3: fix perform... |
2760 |
* the flush returns error? Do we need to check for ATTR_MTIME_SET flag? |
0f4d634c5 cifs: flush data ... |
2761 |
*/ |
cf5371ae4 smb3: fix perform... |
2762 2763 2764 2765 2766 2767 2768 |
if (attrs->ia_valid & (ATTR_MTIME | ATTR_SIZE | ATTR_CTIME)) { rc = filemap_write_and_wait(inode->i_mapping); if (is_interrupt_error(rc)) { rc = -ERESTARTSYS; goto cifs_setattr_exit; } mapping_set_error(inode->i_mapping, rc); |
9a66396f1 CIFS: Fix error p... |
2769 |
} |
eb4b756b1 cifs: eliminate c... |
2770 |
rc = 0; |
cea218054 [CIFS] Fix potent... |
2771 |
|
cf5371ae4 smb3: fix perform... |
2772 2773 |
if ((attrs->ia_valid & ATTR_MTIME) && !(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC)) { |
86f740f2a cifs: fix rename(... |
2774 |
rc = cifs_get_writable_file(cifsInode, FIND_WR_ANY, &wfile); |
aa081859b cifs: flush befor... |
2775 2776 2777 2778 2779 |
if (!rc) { tcon = tlink_tcon(wfile->tlink); rc = tcon->ses->server->ops->flush(xid, tcon, &wfile->fid); cifsFileInfo_put(wfile); if (rc) |
783bf7b8b cifs: Fix missed ... |
2780 |
goto cifs_setattr_exit; |
aa081859b cifs: flush befor... |
2781 |
} else if (rc != -EBADF) |
783bf7b8b cifs: Fix missed ... |
2782 |
goto cifs_setattr_exit; |
aa081859b cifs: flush befor... |
2783 2784 2785 |
else rc = 0; } |
50531444f [CIFS] Fix mtime ... |
2786 |
if (attrs->ia_valid & ATTR_SIZE) { |
8efdbde64 [CIFS] break ATTR... |
2787 2788 |
rc = cifs_set_file_size(inode, attrs, xid, full_path); if (rc != 0) |
e30dcf3a1 [CIFS] Add suppor... |
2789 |
goto cifs_setattr_exit; |
1da177e4c Linux-2.6.12-rc2 |
2790 |
} |
4ca691a89 silently ignore o... |
2791 |
|
a5ff37696 cifs: Call id to ... |
2792 2793 2794 2795 2796 |
if (attrs->ia_valid & ATTR_UID) uid = attrs->ia_uid; if (attrs->ia_valid & ATTR_GID) gid = attrs->ia_gid; |
22442179a cifs: allow chmod... |
2797 2798 |
if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) || (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID)) { |
8abf2775d cifs: Use kuids a... |
2799 |
if (uid_valid(uid) || gid_valid(gid)) { |
0f22053e8 cifs: Fix unix pe... |
2800 2801 |
mode = NO_CHANGE_64; rc = id_mode_to_cifs_acl(inode, full_path, &mode, |
a5ff37696 cifs: Call id to ... |
2802 2803 |
uid, gid); if (rc) { |
f96637be0 [CIFS] cifs: Rena... |
2804 2805 2806 |
cifs_dbg(FYI, "%s: Setting id failed with error: %d ", __func__, rc); |
a5ff37696 cifs: Call id to ... |
2807 2808 2809 2810 |
goto cifs_setattr_exit; } } } else |
3fe5c1dd0 spin off cifs_set... |
2811 |
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)) |
4ca691a89 silently ignore o... |
2812 |
attrs->ia_valid &= ~(ATTR_UID | ATTR_GID); |
1da177e4c Linux-2.6.12-rc2 |
2813 |
|
d32c4f262 CIFS: ignore mode... |
2814 2815 2816 |
/* skip mode change if it's just for clearing setuid/setgid */ if (attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID)) attrs->ia_valid &= ~ATTR_MODE; |
1da177e4c Linux-2.6.12-rc2 |
2817 |
if (attrs->ia_valid & ATTR_MODE) { |
1da177e4c Linux-2.6.12-rc2 |
2818 |
mode = attrs->ia_mode; |
cdbce9c87 [CIFS] Fix setatt... |
2819 |
rc = 0; |
22442179a cifs: allow chmod... |
2820 2821 |
if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) || (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID)) { |
0f22053e8 cifs: Fix unix pe... |
2822 |
rc = id_mode_to_cifs_acl(inode, full_path, &mode, |
8abf2775d cifs: Use kuids a... |
2823 |
INVALID_UID, INVALID_GID); |
78415d2d3 cifs: Misc. clean... |
2824 |
if (rc) { |
f96637be0 [CIFS] cifs: Rena... |
2825 2826 2827 |
cifs_dbg(FYI, "%s: Setting ACL failed with error: %d ", __func__, rc); |
78415d2d3 cifs: Misc. clean... |
2828 2829 |
goto cifs_setattr_exit; } |
0f22053e8 cifs: Fix unix pe... |
2830 2831 2832 2833 2834 2835 2836 |
/* * In case of CIFS_MOUNT_CIFS_ACL, we cannot support all modes. * Pick up the actual mode bits that were set. */ if (mode != attrs->ia_mode) attrs->ia_mode = mode; |
78415d2d3 cifs: Misc. clean... |
2837 |
} else |
5132861a7 disable most mode... |
2838 2839 |
if (((mode & S_IWUGO) == 0) && (cifsInode->cifsAttrs & ATTR_READONLY) == 0) { |
feb3e20ce move file time an... |
2840 2841 |
dosattr = cifsInode->cifsAttrs | ATTR_READONLY; |
5132861a7 disable most mode... |
2842 2843 2844 2845 2846 |
/* fix up mode if we're not using dynperm */ if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) == 0) attrs->ia_mode = inode->i_mode & ~S_IWUGO; } else if ((mode & S_IWUGO) && (cifsInode->cifsAttrs & ATTR_READONLY)) { |
feb3e20ce move file time an... |
2847 2848 2849 2850 2851 |
dosattr = cifsInode->cifsAttrs & ~ATTR_READONLY; /* Attributes of 0 are ignored */ if (dosattr == 0) dosattr |= ATTR_NORMAL; |
5132861a7 disable most mode... |
2852 2853 2854 2855 2856 2857 |
/* reset local inode permissions to normal */ if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) { attrs->ia_mode &= ~(S_IALLUGO); if (S_ISDIR(inode->i_mode)) attrs->ia_mode |= |
8401e9367 cifs: remove [gu]... |
2858 |
cifs_sb->ctx->dir_mode; |
5132861a7 disable most mode... |
2859 2860 |
else attrs->ia_mode |= |
8401e9367 cifs: remove [gu]... |
2861 |
cifs_sb->ctx->file_mode; |
5132861a7 disable most mode... |
2862 2863 2864 2865 |
} } else if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) { /* ignore mode change - ATTR_READONLY hasn't changed */ attrs->ia_valid &= ~ATTR_MODE; |
1da177e4c Linux-2.6.12-rc2 |
2866 |
} |
1da177e4c Linux-2.6.12-rc2 |
2867 |
} |
feb3e20ce move file time an... |
2868 2869 2870 2871 |
if (attrs->ia_valid & (ATTR_MTIME|ATTR_ATIME|ATTR_CTIME) || ((attrs->ia_valid & ATTR_MODE) && dosattr)) { rc = cifs_set_file_info(inode, attrs, xid, full_path, dosattr); /* BB: check for rc = -EOPNOTSUPP and switch to legacy mode */ |
1da177e4c Linux-2.6.12-rc2 |
2872 |
|
e30dcf3a1 [CIFS] Add suppor... |
2873 2874 2875 2876 2877 |
/* Even if error on time set, no sense failing the call if the server would set the time to a reasonable value anyway, and this check ensures that we are not being called from sys_utimes in which case we ought to fail the call back to the user when the server rejects the call */ |
fb8c4b14d [CIFS] whitespace... |
2878 |
if ((rc) && (attrs->ia_valid & |
feb3e20ce move file time an... |
2879 |
(ATTR_MODE | ATTR_GID | ATTR_UID | ATTR_SIZE))) |
e30dcf3a1 [CIFS] Add suppor... |
2880 |
rc = 0; |
1da177e4c Linux-2.6.12-rc2 |
2881 2882 2883 2884 |
} /* do not need local check to inode_check_ok since the server does that */ |
1025774ce remove inode_setattr |
2885 2886 2887 2888 |
if (rc) goto cifs_setattr_exit; if ((attrs->ia_valid & ATTR_SIZE) && |
1b9474635 cifs: truncate fa... |
2889 2890 |
attrs->ia_size != i_size_read(inode)) truncate_setsize(inode, attrs->ia_size); |
1025774ce remove inode_setattr |
2891 |
|
2f221d6f7 attr: handle idma... |
2892 |
setattr_copy(&init_user_ns, inode, attrs); |
1025774ce remove inode_setattr |
2893 |
mark_inode_dirty(inode); |
1025774ce remove inode_setattr |
2894 |
|
e30dcf3a1 [CIFS] Add suppor... |
2895 |
cifs_setattr_exit: |
6d5786a34 CIFS: Rename Get/... |
2896 |
free_xid(xid); |
f6a9bc336 cifs: allocate bu... |
2897 |
free_dentry_path(page); |
1da177e4c Linux-2.6.12-rc2 |
2898 2899 |
return rc; } |
0510eeb73 turn cifs_setattr... |
2900 |
int |
549c72977 fs: make helpers ... |
2901 2902 |
cifs_setattr(struct user_namespace *mnt_userns, struct dentry *direntry, struct iattr *attrs) |
0510eeb73 turn cifs_setattr... |
2903 |
{ |
fc64005c9 don't bother with... |
2904 |
struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb); |
96daf2b09 [CIFS] Rename thr... |
2905 |
struct cifs_tcon *pTcon = cifs_sb_master_tcon(cifs_sb); |
c6cc4c5a7 cifs: handle -EIN... |
2906 |
int rc, retries = 0; |
0510eeb73 turn cifs_setattr... |
2907 |
|
087f757b0 cifs: add shutdow... |
2908 2909 |
if (unlikely(cifs_forced_shutdown(cifs_sb))) return -EIO; |
c6cc4c5a7 cifs: handle -EIN... |
2910 2911 2912 2913 2914 2915 2916 |
do { if (pTcon->unix_ext) rc = cifs_setattr_unix(direntry, attrs); else rc = cifs_setattr_nounix(direntry, attrs); retries++; } while (is_retryable_error(rc) && retries < 2); |
0510eeb73 turn cifs_setattr... |
2917 2918 |
/* BB: add cifs_setattr_legacy for really old servers */ |
c6cc4c5a7 cifs: handle -EIN... |
2919 |
return rc; |
0510eeb73 turn cifs_setattr... |
2920 |
} |