Blame view
fs/cifs/inode.c
63 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 |
/* * fs/cifs/inode.c * |
f19159dc5 [CIFS] Cleanup va... |
4 |
* Copyright (C) International Business Machines Corp., 2002,2010 |
1da177e4c Linux-2.6.12-rc2 |
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
* Author(s): Steve French (sfrench@us.ibm.com) * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <linux/fs.h> |
1da177e4c Linux-2.6.12-rc2 |
22 |
#include <linux/stat.h> |
5a0e3ad6a include cleanup: ... |
23 |
#include <linux/slab.h> |
1da177e4c Linux-2.6.12-rc2 |
24 |
#include <linux/pagemap.h> |
4f73c7d34 cifs: fix potenti... |
25 |
#include <linux/freezer.h> |
1da177e4c Linux-2.6.12-rc2 |
26 27 28 29 30 31 32 |
#include <asm/div64.h> #include "cifsfs.h" #include "cifspdu.h" #include "cifsglob.h" #include "cifsproto.h" #include "cifs_debug.h" #include "cifs_fs_sb.h" |
2baa26825 Remap reserved po... |
33 |
#include "cifs_unicode.h" |
9451a9a52 cifs: define inod... |
34 |
#include "fscache.h" |
1da177e4c Linux-2.6.12-rc2 |
35 |
|
70eff55d2 [CIFS] factoring ... |
36 |
|
01c64feac CIFS: Use d_autom... |
37 |
static void cifs_set_ops(struct inode *inode) |
70eff55d2 [CIFS] factoring ... |
38 39 40 41 42 43 44 45 46 47 48 |
{ 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... |
49 50 51 52 53 |
} 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 ... |
54 55 56 57 58 |
} 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 ... |
59 |
/* check if server can support readpages */ |
0d424ad0a cifs: add cifs_sb... |
60 |
if (cifs_sb_master_tcon(cifs_sb)->ses->server->maxBuf < |
09cbfeaf1 mm, fs: get rid o... |
61 |
PAGE_SIZE + MAX_CIFS_HDR_SIZE) |
70eff55d2 [CIFS] factoring ... |
62 63 64 65 66 |
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 ... |
67 |
#ifdef CONFIG_CIFS_DFS_UPCALL |
01c64feac CIFS: Use d_autom... |
68 |
if (IS_AUTOMOUNT(inode)) { |
7962670e6 [CIFS] DFS patch... |
69 70 |
inode->i_op = &cifs_dfs_referral_inode_operations; } else { |
bc5b6e24a [CIFS] Fix build ... |
71 72 73 |
#else /* NO DFS support, treat as a directory */ { #endif |
7962670e6 [CIFS] DFS patch... |
74 75 76 |
inode->i_op = &cifs_dir_inode_ops; inode->i_fop = &cifs_dir_ops; } |
70eff55d2 [CIFS] factoring ... |
77 78 79 80 81 82 83 84 85 |
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... |
86 87 88 89 90 91 92 |
/* 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... |
93 94 95 |
cifs_dbg(FYI, "%s: revalidating inode %llu ", __func__, cifs_i->uniqueid); |
df2cf170c cifs: overhaul ci... |
96 97 |
if (inode->i_state & I_NEW) { |
f96637be0 [CIFS] cifs: Rena... |
98 99 100 |
cifs_dbg(FYI, "%s: inode %llu is new ", __func__, cifs_i->uniqueid); |
df2cf170c cifs: overhaul ci... |
101 102 103 104 |
return; } /* don't bother with revalidation if we have an oplock */ |
18cceb6a7 CIFS: Replace cli... |
105 |
if (CIFS_CACHE_READ(cifs_i)) { |
f96637be0 [CIFS] cifs: Rena... |
106 107 108 |
cifs_dbg(FYI, "%s: inode %llu is oplocked ", __func__, cifs_i->uniqueid); |
df2cf170c cifs: overhaul ci... |
109 110 111 112 113 114 |
return; } /* revalidate if mtime or size have changed */ if (timespec_equal(&inode->i_mtime, &fattr->cf_mtime) && cifs_i->server_eof == fattr->cf_eof) { |
f96637be0 [CIFS] cifs: Rena... |
115 116 117 |
cifs_dbg(FYI, "%s: inode %llu is unchanged ", __func__, cifs_i->uniqueid); |
df2cf170c cifs: overhaul ci... |
118 119 |
return; } |
f96637be0 [CIFS] cifs: Rena... |
120 121 122 |
cifs_dbg(FYI, "%s: invalidating inode %llu mapping ", __func__, cifs_i->uniqueid); |
aff8d5ca7 cifs: convert boo... |
123 |
set_bit(CIFS_INO_INVALID_MAPPING, &cifs_i->flags); |
df2cf170c cifs: overhaul ci... |
124 |
} |
74d290da4 [CIFS] Provide sa... |
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
/* * 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... |
151 152 153 |
/* populate an inode with info from a cifs_fattr struct */ void cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr) |
75f12983d [CIFS] consolidat... |
154 |
{ |
cc0bad755 cifs: add new cif... |
155 |
struct cifsInodeInfo *cifs_i = CIFS_I(inode); |
0b8f18e35 cifs: convert cif... |
156 |
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
cc0bad755 cifs: add new cif... |
157 |
|
df2cf170c cifs: overhaul ci... |
158 |
cifs_revalidate_cache(inode, fattr); |
b7ca69289 CIFS: Protect i_n... |
159 |
spin_lock(&inode->i_lock); |
cc0bad755 cifs: add new cif... |
160 161 162 |
inode->i_atime = fattr->cf_atime; inode->i_mtime = fattr->cf_mtime; inode->i_ctime = fattr->cf_ctime; |
cc0bad755 cifs: add new cif... |
163 |
inode->i_rdev = fattr->cf_rdev; |
74d290da4 [CIFS] Provide sa... |
164 |
cifs_nlink_fattr_to_inode(inode, fattr); |
cc0bad755 cifs: add new cif... |
165 166 |
inode->i_uid = fattr->cf_uid; inode->i_gid = fattr->cf_gid; |
0b8f18e35 cifs: convert cif... |
167 168 169 170 |
/* 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... |
171 |
cifs_i->cifsAttrs = fattr->cf_cifsattrs; |
75f12983d [CIFS] consolidat... |
172 |
|
0b8f18e35 cifs: convert cif... |
173 174 175 176 |
if (fattr->cf_flags & CIFS_FATTR_NEED_REVAL) cifs_i->time = 0; else cifs_i->time = jiffies; |
aff8d5ca7 cifs: convert boo... |
177 178 179 180 |
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... |
181 |
|
835a36ca4 cifs: set server_... |
182 |
cifs_i->server_eof = fattr->cf_eof; |
cc0bad755 cifs: add new cif... |
183 184 185 186 |
/* * Can't safely change the file size here if the client is writing to * it due to potential races. */ |
cc0bad755 cifs: add new cif... |
187 188 189 190 191 192 193 194 195 196 197 |
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... |
198 199 |
if (fattr->cf_flags & CIFS_FATTR_DFS_REFERRAL) inode->i_flags |= S_AUTOMOUNT; |
c2b93e069 cifs: only set op... |
200 201 |
if (inode->i_state & I_NEW) cifs_set_ops(inode); |
cc0bad755 cifs: add new cif... |
202 |
} |
4065c802d cifs: fix noserve... |
203 204 205 206 207 208 209 210 211 212 |
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... |
213 214 215 216 217 218 219 220 221 222 223 224 225 226 |
/* 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); fattr->cf_mode = le64_to_cpu(info->Permissions); |
75f12983d [CIFS] consolidat... |
227 228 229 230 231 |
/* * 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... |
232 |
fattr->cf_mode &= ~S_IFMT; |
75f12983d [CIFS] consolidat... |
233 234 |
switch (le32_to_cpu(info->Type)) { case UNIX_FILE: |
cc0bad755 cifs: add new cif... |
235 236 |
fattr->cf_mode |= S_IFREG; fattr->cf_dtype = DT_REG; |
75f12983d [CIFS] consolidat... |
237 238 |
break; case UNIX_SYMLINK: |
cc0bad755 cifs: add new cif... |
239 240 |
fattr->cf_mode |= S_IFLNK; fattr->cf_dtype = DT_LNK; |
75f12983d [CIFS] consolidat... |
241 242 |
break; case UNIX_DIR: |
cc0bad755 cifs: add new cif... |
243 244 |
fattr->cf_mode |= S_IFDIR; fattr->cf_dtype = DT_DIR; |
75f12983d [CIFS] consolidat... |
245 246 |
break; case UNIX_CHARDEV: |
cc0bad755 cifs: add new cif... |
247 248 249 250 |
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... |
251 252 |
break; case UNIX_BLOCKDEV: |
cc0bad755 cifs: add new cif... |
253 254 255 256 |
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... |
257 258 |
break; case UNIX_FIFO: |
cc0bad755 cifs: add new cif... |
259 260 |
fattr->cf_mode |= S_IFIFO; fattr->cf_dtype = DT_FIFO; |
75f12983d [CIFS] consolidat... |
261 262 |
break; case UNIX_SOCKET: |
cc0bad755 cifs: add new cif... |
263 264 |
fattr->cf_mode |= S_IFSOCK; fattr->cf_dtype = DT_SOCK; |
75f12983d [CIFS] consolidat... |
265 266 267 |
break; default: /* safest to call it a file if we do not know */ |
cc0bad755 cifs: add new cif... |
268 269 |
fattr->cf_mode |= S_IFREG; fattr->cf_dtype = DT_REG; |
f96637be0 [CIFS] cifs: Rena... |
270 271 |
cifs_dbg(FYI, "unknown type %d ", le32_to_cpu(info->Type)); |
75f12983d [CIFS] consolidat... |
272 273 |
break; } |
46bbc25f9 cifs: Override un... |
274 275 276 |
fattr->cf_uid = cifs_sb->mnt_uid; if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)) { u64 id = le64_to_cpu(info->Uid); |
4a2c8cf56 cifs: Convert str... |
277 278 279 280 281 |
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... |
282 283 284 285 286 |
} fattr->cf_gid = cifs_sb->mnt_gid; if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)) { u64 id = le64_to_cpu(info->Gid); |
4a2c8cf56 cifs: Convert str... |
287 288 289 290 291 |
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... |
292 |
} |
75f12983d [CIFS] consolidat... |
293 |
|
cc0bad755 cifs: add new cif... |
294 |
fattr->cf_nlink = le64_to_cpu(info->Nlinks); |
75f12983d [CIFS] consolidat... |
295 |
} |
b9a3260f2 [CIFS] Enable DFS... |
296 |
/* |
cc0bad755 cifs: add new cif... |
297 298 299 300 301 |
* 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... |
302 |
*/ |
f1230c979 [CIFS] fix sparse... |
303 |
static void |
cc0bad755 cifs: add new cif... |
304 |
cifs_create_dfs_fattr(struct cifs_fattr *fattr, struct super_block *sb) |
0e4bbde94 [CIFS] Enable DFS... |
305 |
{ |
cc0bad755 cifs: add new cif... |
306 |
struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
0e4bbde94 [CIFS] Enable DFS... |
307 |
|
f96637be0 [CIFS] cifs: Rena... |
308 309 |
cifs_dbg(FYI, "creating fake fattr for DFS referral "); |
cc0bad755 cifs: add new cif... |
310 311 312 313 314 315 316 317 318 319 |
memset(fattr, 0, sizeof(*fattr)); fattr->cf_mode = S_IFDIR | S_IXUGO | S_IRWXU; fattr->cf_uid = cifs_sb->mnt_uid; fattr->cf_gid = cifs_sb->mnt_gid; fattr->cf_atime = CURRENT_TIME; fattr->cf_ctime = CURRENT_TIME; fattr->cf_mtime = CURRENT_TIME; fattr->cf_nlink = 2; fattr->cf_flags |= CIFS_FATTR_DFS_REFERRAL; |
0e4bbde94 [CIFS] Enable DFS... |
320 |
} |
4ad650445 CIFS: Move guery ... |
321 322 |
static int cifs_get_file_info_unix(struct file *filp) |
abab095d1 cifs: add cifs_re... |
323 324 |
{ int rc; |
6d5786a34 CIFS: Rename Get/... |
325 |
unsigned int xid; |
abab095d1 cifs: add cifs_re... |
326 327 |
FILE_UNIX_BASIC_INFO find_data; struct cifs_fattr fattr; |
496ad9aa8 new helper: file_... |
328 |
struct inode *inode = file_inode(filp); |
abab095d1 cifs: add cifs_re... |
329 |
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
c21dfb699 fs/cifs: Remove u... |
330 |
struct cifsFileInfo *cfile = filp->private_data; |
96daf2b09 [CIFS] Rename thr... |
331 |
struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); |
abab095d1 cifs: add cifs_re... |
332 |
|
6d5786a34 CIFS: Rename Get/... |
333 |
xid = get_xid(); |
4b4de76e3 CIFS: Replace net... |
334 |
rc = CIFSSMBUnixQFileInfo(xid, tcon, cfile->fid.netfid, &find_data); |
abab095d1 cifs: add cifs_re... |
335 336 337 338 339 340 341 342 |
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; } cifs_fattr_to_inode(inode, &fattr); |
6d5786a34 CIFS: Rename Get/... |
343 |
free_xid(xid); |
abab095d1 cifs: add cifs_re... |
344 345 |
return rc; } |
1da177e4c Linux-2.6.12-rc2 |
346 |
int cifs_get_inode_info_unix(struct inode **pinode, |
cc0bad755 cifs: add new cif... |
347 |
const unsigned char *full_path, |
6d5786a34 CIFS: Rename Get/... |
348 |
struct super_block *sb, unsigned int xid) |
1da177e4c Linux-2.6.12-rc2 |
349 |
{ |
cc0bad755 cifs: add new cif... |
350 |
int rc; |
0e4bbde94 [CIFS] Enable DFS... |
351 |
FILE_UNIX_BASIC_INFO find_data; |
cc0bad755 cifs: add new cif... |
352 |
struct cifs_fattr fattr; |
96daf2b09 [CIFS] Rename thr... |
353 |
struct cifs_tcon *tcon; |
7ffec3724 cifs: add refcoun... |
354 |
struct tcon_link *tlink; |
1da177e4c Linux-2.6.12-rc2 |
355 |
struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
1da177e4c Linux-2.6.12-rc2 |
356 |
|
f96637be0 [CIFS] cifs: Rena... |
357 358 |
cifs_dbg(FYI, "Getting info on %s ", full_path); |
7962670e6 [CIFS] DFS patch... |
359 |
|
7ffec3724 cifs: add refcoun... |
360 361 362 363 |
tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) return PTR_ERR(tlink); tcon = tlink_tcon(tlink); |
1da177e4c Linux-2.6.12-rc2 |
364 |
/* could have done a find first instead but this returns more info */ |
cc0bad755 cifs: add new cif... |
365 |
rc = CIFSSMBUnixQPathInfo(xid, tcon, full_path, &find_data, |
bc8ebdc4f Fix that several ... |
366 |
cifs_sb->local_nls, cifs_remap(cifs_sb)); |
7ffec3724 cifs: add refcoun... |
367 |
cifs_put_tlink(tlink); |
e911d0cc8 cifs: fix inode l... |
368 |
|
cc0bad755 cifs: add new cif... |
369 370 371 372 373 374 375 376 |
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 |
377 |
|
1b12b9c15 cifs: use Minshal... |
378 379 |
/* check for Minshall+French symlinks */ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) { |
cb084b1a9 cifs: Rename MF s... |
380 381 |
int tmprc = check_mf_symlink(xid, tcon, cifs_sb, &fattr, full_path); |
1b12b9c15 cifs: use Minshal... |
382 |
if (tmprc) |
cb084b1a9 cifs: Rename MF s... |
383 384 |
cifs_dbg(FYI, "check_mf_symlink: %d ", tmprc); |
1b12b9c15 cifs: use Minshal... |
385 |
} |
0e4bbde94 [CIFS] Enable DFS... |
386 |
if (*pinode == NULL) { |
cc0bad755 cifs: add new cif... |
387 |
/* get new inode */ |
4065c802d cifs: fix noserve... |
388 |
cifs_fill_uniqueid(sb, &fattr); |
cc0bad755 cifs: add new cif... |
389 390 |
*pinode = cifs_iget(sb, &fattr); if (!*pinode) |
0e4bbde94 [CIFS] Enable DFS... |
391 |
rc = -ENOMEM; |
cc0bad755 cifs: add new cif... |
392 393 |
} else { /* we already have inode, update it */ |
7196ac113 Fix to check Uniq... |
394 395 396 397 398 399 400 401 402 403 404 405 406 407 |
/* if uniqueid is different, return error */ if (unlikely(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM && CIFS_I(*pinode)->uniqueid != fattr.cf_uniqueid)) { rc = -ESTALE; goto cgiiu_exit; } /* if filetype is different, return error */ if (unlikely(((*pinode)->i_mode & S_IFMT) != (fattr.cf_mode & S_IFMT))) { rc = -ESTALE; goto cgiiu_exit; } |
cc0bad755 cifs: add new cif... |
408 |
cifs_fattr_to_inode(*pinode, &fattr); |
0e4bbde94 [CIFS] Enable DFS... |
409 |
} |
1da177e4c Linux-2.6.12-rc2 |
410 |
|
7196ac113 Fix to check Uniq... |
411 |
cgiiu_exit: |
1da177e4c Linux-2.6.12-rc2 |
412 413 |
return rc; } |
0b8f18e35 cifs: convert cif... |
414 |
static int |
0360d605a CIFS: Remove extr... |
415 |
cifs_sfu_type(struct cifs_fattr *fattr, const char *path, |
6d5786a34 CIFS: Rename Get/... |
416 |
struct cifs_sb_info *cifs_sb, unsigned int xid) |
d6e2f2a4c [CIFS] Recognize ... |
417 418 |
{ int rc; |
db8b631d4 Allow mknod and m... |
419 |
__u32 oplock; |
7ffec3724 cifs: add refcoun... |
420 |
struct tcon_link *tlink; |
96daf2b09 [CIFS] Rename thr... |
421 |
struct cifs_tcon *tcon; |
d81b8a40e CIFS: Cleanup cif... |
422 423 |
struct cifs_fid fid; struct cifs_open_parms oparms; |
d4ffff1fa CIFS: Add rwpidfo... |
424 |
struct cifs_io_parms io_parms; |
86c96b4bb [CIFS] Fix mknod ... |
425 |
char buf[24]; |
d6e2f2a4c [CIFS] Recognize ... |
426 |
unsigned int bytes_read; |
fb8c4b14d [CIFS] whitespace... |
427 |
char *pbuf; |
0360d605a CIFS: Remove extr... |
428 |
int buf_type = CIFS_NO_BUFFER; |
d6e2f2a4c [CIFS] Recognize ... |
429 430 |
pbuf = buf; |
0b8f18e35 cifs: convert cif... |
431 432 433 434 435 |
fattr->cf_mode &= ~S_IFMT; if (fattr->cf_eof == 0) { fattr->cf_mode |= S_IFIFO; fattr->cf_dtype = DT_FIFO; |
d6e2f2a4c [CIFS] Recognize ... |
436 |
return 0; |
0b8f18e35 cifs: convert cif... |
437 438 439 |
} else if (fattr->cf_eof < 8) { fattr->cf_mode |= S_IFREG; fattr->cf_dtype = DT_REG; |
d6e2f2a4c [CIFS] Recognize ... |
440 441 |
return -EINVAL; /* EOPNOTSUPP? */ } |
50c2f7538 [CIFS] whitespace... |
442 |
|
7ffec3724 cifs: add refcoun... |
443 444 445 446 |
tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) return PTR_ERR(tlink); tcon = tlink_tcon(tlink); |
d81b8a40e CIFS: Cleanup cif... |
447 448 449 450 451 452 453 454 |
oparms.tcon = tcon; oparms.cifs_sb = cifs_sb; oparms.desired_access = GENERIC_READ; oparms.create_options = CREATE_NOT_DIR; oparms.disposition = FILE_OPEN; oparms.path = path; oparms.fid = &fid; oparms.reconnect = false; |
db8b631d4 Allow mknod and m... |
455 456 457 458 459 |
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... |
460 |
if (rc) { |
db8b631d4 Allow mknod and m... |
461 462 |
cifs_dbg(FYI, "check sfu type of %s, open rc = %d ", path, rc); |
0360d605a CIFS: Remove extr... |
463 464 465 466 467 |
cifs_put_tlink(tlink); return rc; } /* Read header */ |
d81b8a40e CIFS: Cleanup cif... |
468 |
io_parms.netfid = fid.netfid; |
0360d605a CIFS: Remove extr... |
469 470 471 472 |
io_parms.pid = current->tgid; io_parms.tcon = tcon; io_parms.offset = 0; io_parms.length = 24; |
db8b631d4 Allow mknod and m... |
473 474 |
rc = tcon->ses->server->ops->sync_read(xid, &fid, &io_parms, &bytes_read, &pbuf, &buf_type); |
0360d605a CIFS: Remove extr... |
475 476 477 478 479 480 481 482 483 484 485 486 487 |
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 ... |
488 |
} |
0360d605a CIFS: Remove extr... |
489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 |
} 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... |
507 |
} else { |
0360d605a CIFS: Remove extr... |
508 |
fattr->cf_mode |= S_IFREG; /* file? */ |
0b8f18e35 cifs: convert cif... |
509 |
fattr->cf_dtype = DT_REG; |
0360d605a CIFS: Remove extr... |
510 |
rc = -EOPNOTSUPP; |
fb8c4b14d [CIFS] whitespace... |
511 |
} |
0360d605a CIFS: Remove extr... |
512 513 514 515 |
} 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 ... |
516 |
} |
db8b631d4 Allow mknod and m... |
517 518 |
tcon->ses->server->ops->close(xid, tcon, &fid); |
7ffec3724 cifs: add refcoun... |
519 |
cifs_put_tlink(tlink); |
d6e2f2a4c [CIFS] Recognize ... |
520 |
return rc; |
d6e2f2a4c [CIFS] Recognize ... |
521 |
} |
9e294f1c4 [CIFS] Recognize ... |
522 |
#define SFBITS_MASK (S_ISVTX | S_ISGID | S_ISUID) /* SETFILEBITS valid bits */ |
0b8f18e35 cifs: convert cif... |
523 524 525 526 527 528 |
/* * 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/... |
529 |
struct cifs_sb_info *cifs_sb, unsigned int xid) |
9e294f1c4 [CIFS] Recognize ... |
530 |
{ |
3020a1f58 [CIFS] Fix schedu... |
531 |
#ifdef CONFIG_CIFS_XATTR |
9e294f1c4 [CIFS] Recognize ... |
532 533 534 |
ssize_t rc; char ea_value[4]; __u32 mode; |
7ffec3724 cifs: add refcoun... |
535 |
struct tcon_link *tlink; |
96daf2b09 [CIFS] Rename thr... |
536 |
struct cifs_tcon *tcon; |
7ffec3724 cifs: add refcoun... |
537 538 539 540 541 |
tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) return PTR_ERR(tlink); tcon = tlink_tcon(tlink); |
9e294f1c4 [CIFS] Recognize ... |
542 |
|
d979f3b0a Add protocol spec... |
543 544 545 546 547 548 549 550 |
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 */, cifs_sb->local_nls, |
2baa26825 Remap reserved po... |
551 |
cifs_remap(cifs_sb)); |
7ffec3724 cifs: add refcoun... |
552 |
cifs_put_tlink(tlink); |
4523cc304 [CIFS] UID/GID ov... |
553 |
if (rc < 0) |
9e294f1c4 [CIFS] Recognize ... |
554 555 556 |
return (int)rc; else if (rc > 3) { mode = le32_to_cpu(*((__le32 *)ea_value)); |
0b8f18e35 cifs: convert cif... |
557 |
fattr->cf_mode &= ~SFBITS_MASK; |
f96637be0 [CIFS] cifs: Rena... |
558 559 560 |
cifs_dbg(FYI, "special bits 0%o org mode 0%o ", mode, fattr->cf_mode); |
0b8f18e35 cifs: convert cif... |
561 |
fattr->cf_mode = (mode & SFBITS_MASK) | fattr->cf_mode; |
f96637be0 [CIFS] cifs: Rena... |
562 563 |
cifs_dbg(FYI, "special mode bits 0%o ", mode); |
9e294f1c4 [CIFS] Recognize ... |
564 |
} |
0b8f18e35 cifs: convert cif... |
565 566 |
return 0; |
3020a1f58 [CIFS] Fix schedu... |
567 568 569 |
#else return -EOPNOTSUPP; #endif |
9e294f1c4 [CIFS] Recognize ... |
570 |
} |
0b8f18e35 cifs: convert cif... |
571 |
/* Fill a cifs_fattr struct with info from FILE_ALL_INFO */ |
f1230c979 [CIFS] fix sparse... |
572 |
static void |
0b8f18e35 cifs: convert cif... |
573 |
cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info, |
eb85d94bd CIFS: Fix symboli... |
574 575 |
struct cifs_sb_info *cifs_sb, bool adjust_tz, bool symlink) |
b9a3260f2 [CIFS] Enable DFS... |
576 |
{ |
96daf2b09 [CIFS] Rename thr... |
577 |
struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); |
0d424ad0a cifs: add cifs_sb... |
578 |
|
0b8f18e35 cifs: convert cif... |
579 580 581 582 583 584 585 586 587 588 589 590 591 592 |
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); else fattr->cf_atime = CURRENT_TIME; fattr->cf_ctime = cifs_NTtimeToUnix(info->ChangeTime); fattr->cf_mtime = cifs_NTtimeToUnix(info->LastWriteTime); if (adjust_tz) { |
0d424ad0a cifs: add cifs_sb... |
593 594 |
fattr->cf_ctime.tv_sec += tcon->ses->server->timeAdj; fattr->cf_mtime.tv_sec += tcon->ses->server->timeAdj; |
0b8f18e35 cifs: convert cif... |
595 596 597 598 |
} fattr->cf_eof = le64_to_cpu(info->EndOfFile); fattr->cf_bytes = le64_to_cpu(info->AllocationSize); |
20054bd65 cifs: use Creatio... |
599 |
fattr->cf_createtime = le64_to_cpu(info->CreationTime); |
0b8f18e35 cifs: convert cif... |
600 |
|
74d290da4 [CIFS] Provide sa... |
601 |
fattr->cf_nlink = le32_to_cpu(info->NumberOfLinks); |
eb85d94bd CIFS: Fix symboli... |
602 603 604 605 606 |
if (symlink) { fattr->cf_mode = S_IFLNK; fattr->cf_dtype = DT_LNK; } else if (fattr->cf_cifsattrs & ATTR_DIRECTORY) { |
0b8f18e35 cifs: convert cif... |
607 608 |
fattr->cf_mode = S_IFDIR | cifs_sb->mnt_dir_mode; fattr->cf_dtype = DT_DIR; |
6de2ce423 CIFS: Fix mkdir/r... |
609 610 611 612 |
/* * Server can return wrong NumberOfLinks value for directories * when Unix extensions are disabled - fake it. */ |
74d290da4 [CIFS] Provide sa... |
613 614 |
if (!tcon->unix_ext) fattr->cf_flags |= CIFS_FATTR_UNKNOWN_NLINK; |
0b8f18e35 cifs: convert cif... |
615 616 617 |
} else { fattr->cf_mode = S_IFREG | cifs_sb->mnt_file_mode; fattr->cf_dtype = DT_REG; |
0b8f18e35 cifs: convert cif... |
618 |
|
d0c280d26 cifs: when ATTR_R... |
619 620 621 |
/* clear write bits if ATTR_READONLY is set */ if (fattr->cf_cifsattrs & ATTR_READONLY) fattr->cf_mode &= ~(S_IWUGO); |
0b8f18e35 cifs: convert cif... |
622 |
|
74d290da4 [CIFS] Provide sa... |
623 624 625 626 627 628 629 630 |
/* * 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) { cifs_dbg(1, "bogus file nlink value %u ", |
6658b9f70 [CIFS] use sensib... |
631 |
fattr->cf_nlink); |
74d290da4 [CIFS] Provide sa... |
632 |
fattr->cf_flags |= CIFS_FATTR_UNKNOWN_NLINK; |
6658b9f70 [CIFS] use sensib... |
633 |
} |
6de2ce423 CIFS: Fix mkdir/r... |
634 |
} |
0b8f18e35 cifs: convert cif... |
635 636 637 |
fattr->cf_uid = cifs_sb->mnt_uid; fattr->cf_gid = cifs_sb->mnt_gid; |
b9a3260f2 [CIFS] Enable DFS... |
638 |
} |
4ad650445 CIFS: Move guery ... |
639 640 |
static int cifs_get_file_info(struct file *filp) |
abab095d1 cifs: add cifs_re... |
641 642 |
{ int rc; |
6d5786a34 CIFS: Rename Get/... |
643 |
unsigned int xid; |
abab095d1 cifs: add cifs_re... |
644 645 |
FILE_ALL_INFO find_data; struct cifs_fattr fattr; |
496ad9aa8 new helper: file_... |
646 |
struct inode *inode = file_inode(filp); |
abab095d1 cifs: add cifs_re... |
647 |
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
c21dfb699 fs/cifs: Remove u... |
648 |
struct cifsFileInfo *cfile = filp->private_data; |
96daf2b09 [CIFS] Rename thr... |
649 |
struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); |
4ad650445 CIFS: Move guery ... |
650 651 652 653 |
struct TCP_Server_Info *server = tcon->ses->server; if (!server->ops->query_file_info) return -ENOSYS; |
abab095d1 cifs: add cifs_re... |
654 |
|
6d5786a34 CIFS: Rename Get/... |
655 |
xid = get_xid(); |
4ad650445 CIFS: Move guery ... |
656 |
rc = server->ops->query_file_info(xid, tcon, &cfile->fid, &find_data); |
42274bb22 CIFS: Fix DFS han... |
657 658 |
switch (rc) { case 0: |
eb85d94bd CIFS: Fix symboli... |
659 660 |
cifs_all_info_to_fattr(&fattr, &find_data, cifs_sb, false, false); |
42274bb22 CIFS: Fix DFS han... |
661 662 663 664 665 666 667 |
break; case -EREMOTE: cifs_create_dfs_fattr(&fattr, inode->i_sb); rc = 0; break; case -EOPNOTSUPP: case -EINVAL: |
abab095d1 cifs: add cifs_re... |
668 669 |
/* * FIXME: legacy server -- fall back to path-based call? |
ff215713e [CIFS] checkpatch... |
670 671 672 |
* for now, just skip revalidating and mark inode for * immediate reval. */ |
abab095d1 cifs: add cifs_re... |
673 674 |
rc = 0; CIFS_I(inode)->time = 0; |
42274bb22 CIFS: Fix DFS han... |
675 |
default: |
abab095d1 cifs: add cifs_re... |
676 |
goto cgfi_exit; |
42274bb22 CIFS: Fix DFS han... |
677 |
} |
abab095d1 cifs: add cifs_re... |
678 679 680 681 682 |
/* * don't bother with SFU junk here -- just mark inode as needing * revalidation. */ |
abab095d1 cifs: add cifs_re... |
683 684 685 686 |
fattr.cf_uniqueid = CIFS_I(inode)->uniqueid; fattr.cf_flags |= CIFS_FATTR_NEED_REVAL; cifs_fattr_to_inode(inode, &fattr); cgfi_exit: |
6d5786a34 CIFS: Rename Get/... |
687 |
free_xid(xid); |
abab095d1 cifs: add cifs_re... |
688 689 |
return rc; } |
1208ef1f7 CIFS: Move query ... |
690 691 692 |
int cifs_get_inode_info(struct inode **inode, const char *full_path, FILE_ALL_INFO *data, struct super_block *sb, int xid, |
42eacf9e5 [CIFS] Fix cifsac... |
693 |
const struct cifs_fid *fid) |
1da177e4c Linux-2.6.12-rc2 |
694 |
{ |
c052e2b42 cifs: obtain file... |
695 696 697 |
bool validinum = false; __u16 srchflgs; int rc = 0, tmprc = ENOSYS; |
1208ef1f7 CIFS: Move query ... |
698 699 |
struct cifs_tcon *tcon; struct TCP_Server_Info *server; |
7ffec3724 cifs: add refcoun... |
700 |
struct tcon_link *tlink; |
1da177e4c Linux-2.6.12-rc2 |
701 |
struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
1da177e4c Linux-2.6.12-rc2 |
702 |
char *buf = NULL; |
1208ef1f7 CIFS: Move query ... |
703 |
bool adjust_tz = false; |
0b8f18e35 cifs: convert cif... |
704 |
struct cifs_fattr fattr; |
c052e2b42 cifs: obtain file... |
705 |
struct cifs_search_info *srchinf = NULL; |
eb85d94bd CIFS: Fix symboli... |
706 |
bool symlink = false; |
1da177e4c Linux-2.6.12-rc2 |
707 |
|
7ffec3724 cifs: add refcoun... |
708 709 710 |
tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) return PTR_ERR(tlink); |
1208ef1f7 CIFS: Move query ... |
711 712 |
tcon = tlink_tcon(tlink); server = tcon->ses->server; |
7ffec3724 cifs: add refcoun... |
713 |
|
f96637be0 [CIFS] cifs: Rena... |
714 715 |
cifs_dbg(FYI, "Getting info on %s ", full_path); |
1da177e4c Linux-2.6.12-rc2 |
716 |
|
1208ef1f7 CIFS: Move query ... |
717 |
if ((data == NULL) && (*inode != NULL)) { |
18cceb6a7 CIFS: Replace cli... |
718 |
if (CIFS_CACHE_READ(CIFS_I(*inode))) { |
f96637be0 [CIFS] cifs: Rena... |
719 720 |
cifs_dbg(FYI, "No need to revalidate cached inode sizes "); |
7ffec3724 cifs: add refcoun... |
721 |
goto cgii_exit; |
1da177e4c Linux-2.6.12-rc2 |
722 723 |
} } |
1208ef1f7 CIFS: Move query ... |
724 725 726 727 728 729 |
/* if inode info is not passed, get it from server */ if (data == NULL) { if (!server->ops->query_path_info) { rc = -ENOSYS; goto cgii_exit; } |
1da177e4c Linux-2.6.12-rc2 |
730 |
buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); |
7ffec3724 cifs: add refcoun... |
731 732 733 734 |
if (buf == NULL) { rc = -ENOMEM; goto cgii_exit; } |
1208ef1f7 CIFS: Move query ... |
735 736 |
data = (FILE_ALL_INFO *)buf; rc = server->ops->query_path_info(xid, tcon, cifs_sb, full_path, |
eb85d94bd CIFS: Fix symboli... |
737 |
data, &adjust_tz, &symlink); |
1da177e4c Linux-2.6.12-rc2 |
738 |
} |
0b8f18e35 cifs: convert cif... |
739 740 |
if (!rc) { |
eb85d94bd CIFS: Fix symboli... |
741 742 |
cifs_all_info_to_fattr(&fattr, data, cifs_sb, adjust_tz, symlink); |
0b8f18e35 cifs: convert cif... |
743 744 |
} else if (rc == -EREMOTE) { cifs_create_dfs_fattr(&fattr, sb); |
b9a3260f2 [CIFS] Enable DFS... |
745 |
rc = 0; |
c052e2b42 cifs: obtain file... |
746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 |
} else if (rc == -EACCES && backup_cred(cifs_sb)) { srchinf = kzalloc(sizeof(struct cifs_search_info), GFP_KERNEL); if (srchinf == NULL) { rc = -ENOMEM; goto cgii_exit; } srchinf->endOfSearch = false; srchinf->info_level = SMB_FIND_FILE_ID_FULL_DIR_INFO; srchflgs = CIFS_SEARCH_CLOSE_ALWAYS | CIFS_SEARCH_CLOSE_AT_END | CIFS_SEARCH_BACKUP_SEARCH; rc = CIFSFindFirst(xid, tcon, full_path, cifs_sb, NULL, srchflgs, srchinf, false); if (!rc) { data = (FILE_ALL_INFO *)srchinf->srch_entries_start; cifs_dir_info_to_fattr(&fattr, (FILE_DIRECTORY_INFO *)data, cifs_sb); fattr.cf_uniqueid = le64_to_cpu( ((SEARCH_ID_FULL_DIR_INFO *)data)->UniqueId); validinum = true; cifs_buf_release(srchinf->ntwrk_buf_start); } kfree(srchinf); |
4c5930e80 Fix warning |
776 777 |
if (rc) goto cgii_exit; |
c052e2b42 cifs: obtain file... |
778 |
} else |
7962670e6 [CIFS] DFS patch... |
779 |
goto cgii_exit; |
1da177e4c Linux-2.6.12-rc2 |
780 |
|
0b8f18e35 cifs: convert cif... |
781 782 783 784 785 786 |
/* * If an inode wasn't passed in, then get the inode number * * Is an i_ino of zero legal? Can we use that to check if the server * supports returning inode numbers? Are there other sanity checks we * can use to ensure that the server is really filling in that field? |
0b8f18e35 cifs: convert cif... |
787 |
*/ |
1208ef1f7 CIFS: Move query ... |
788 |
if (*inode == NULL) { |
b9a3260f2 [CIFS] Enable DFS... |
789 |
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { |
c052e2b42 cifs: obtain file... |
790 791 792 793 794 795 |
if (validinum == false) { if (server->ops->get_srv_inum) tmprc = server->ops->get_srv_inum(xid, tcon, cifs_sb, full_path, &fattr.cf_uniqueid, data); if (tmprc) { |
f96637be0 [CIFS] cifs: Rena... |
796 797 798 |
cifs_dbg(FYI, "GetSrvInodeNum rc %d ", tmprc); |
c052e2b42 cifs: obtain file... |
799 800 801 |
fattr.cf_uniqueid = iunique(sb, ROOT_I); cifs_autodisable_serverino(cifs_sb); } |
132ac7b77 cifs: refactor ne... |
802 |
} |
c052e2b42 cifs: obtain file... |
803 |
} else |
0b8f18e35 cifs: convert cif... |
804 |
fattr.cf_uniqueid = iunique(sb, ROOT_I); |
a108471b5 cifs: Check uniqu... |
805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 |
} else { if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) && validinum == false && server->ops->get_srv_inum) { /* * Pass a NULL tcon to ensure we don't make a round * trip to the server. This only works for SMB2+. */ tmprc = server->ops->get_srv_inum(xid, NULL, cifs_sb, full_path, &fattr.cf_uniqueid, data); if (tmprc) fattr.cf_uniqueid = CIFS_I(*inode)->uniqueid; } else fattr.cf_uniqueid = CIFS_I(*inode)->uniqueid; } |
b9a3260f2 [CIFS] Enable DFS... |
820 |
|
0b8f18e35 cifs: convert cif... |
821 822 823 824 825 |
/* 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... |
826 827 |
cifs_dbg(FYI, "cifs_sfu_type failed: %d ", tmprc); |
b9a3260f2 [CIFS] Enable DFS... |
828 |
} |
1da177e4c Linux-2.6.12-rc2 |
829 |
|
79df1baee cifs: fix use of ... |
830 |
#ifdef CONFIG_CIFS_ACL |
b9a3260f2 [CIFS] Enable DFS... |
831 832 |
/* fill in 0777 bits from ACL */ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { |
1208ef1f7 CIFS: Move query ... |
833 |
rc = cifs_acl_to_fattr(cifs_sb, &fattr, *inode, full_path, fid); |
78415d2d3 cifs: Misc. clean... |
834 |
if (rc) { |
f96637be0 [CIFS] cifs: Rena... |
835 836 837 |
cifs_dbg(FYI, "%s: Getting ACL failed with error: %d ", __func__, rc); |
78415d2d3 cifs: Misc. clean... |
838 839 |
goto cgii_exit; } |
b9a3260f2 [CIFS] Enable DFS... |
840 |
} |
79df1baee cifs: fix use of ... |
841 |
#endif /* CONFIG_CIFS_ACL */ |
b9a3260f2 [CIFS] Enable DFS... |
842 |
|
0b8f18e35 cifs: convert cif... |
843 844 845 |
/* 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... |
846 |
|
1b12b9c15 cifs: use Minshal... |
847 848 |
/* check for Minshall+French symlinks */ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) { |
cb084b1a9 cifs: Rename MF s... |
849 850 |
tmprc = check_mf_symlink(xid, tcon, cifs_sb, &fattr, full_path); |
1b12b9c15 cifs: use Minshal... |
851 |
if (tmprc) |
cb084b1a9 cifs: Rename MF s... |
852 853 |
cifs_dbg(FYI, "check_mf_symlink: %d ", tmprc); |
1b12b9c15 cifs: use Minshal... |
854 |
} |
1208ef1f7 CIFS: Move query ... |
855 856 857 |
if (!*inode) { *inode = cifs_iget(sb, &fattr); if (!*inode) |
0b8f18e35 cifs: convert cif... |
858 859 |
rc = -ENOMEM; } else { |
7196ac113 Fix to check Uniq... |
860 |
/* we already have inode, update it */ |
a108471b5 cifs: Check uniqu... |
861 862 863 864 865 866 |
/* if uniqueid is different, return error */ if (unlikely(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM && CIFS_I(*inode)->uniqueid != fattr.cf_uniqueid)) { rc = -ESTALE; goto cgii_exit; } |
7196ac113 Fix to check Uniq... |
867 868 869 870 871 872 |
/* if filetype is different, return error */ if (unlikely(((*inode)->i_mode & S_IFMT) != (fattr.cf_mode & S_IFMT))) { rc = -ESTALE; goto cgii_exit; } |
1208ef1f7 CIFS: Move query ... |
873 |
cifs_fattr_to_inode(*inode, &fattr); |
0b8f18e35 cifs: convert cif... |
874 |
} |
b9a3260f2 [CIFS] Enable DFS... |
875 |
|
7962670e6 [CIFS] DFS patch... |
876 |
cgii_exit: |
1da177e4c Linux-2.6.12-rc2 |
877 |
kfree(buf); |
7ffec3724 cifs: add refcoun... |
878 |
cifs_put_tlink(tlink); |
1da177e4c Linux-2.6.12-rc2 |
879 880 |
return rc; } |
7f8ed420f [CIFS] CIFS suppo... |
881 882 883 |
static const struct inode_operations cifs_ipc_inode_ops = { .lookup = cifs_lookup, }; |
cc0bad755 cifs: add new cif... |
884 885 886 887 |
static int cifs_find_inode(struct inode *inode, void *opaque) { struct cifs_fattr *fattr = (struct cifs_fattr *) opaque; |
f30b9c118 cifs: don't allow... |
888 |
/* don't match inode with different uniqueid */ |
cc0bad755 cifs: add new cif... |
889 890 |
if (CIFS_I(inode)->uniqueid != fattr->cf_uniqueid) return 0; |
20054bd65 cifs: use Creatio... |
891 892 893 |
/* use createtime like an i_generation field */ if (CIFS_I(inode)->createtime != fattr->cf_createtime) return 0; |
f30b9c118 cifs: don't allow... |
894 895 896 |
/* don't match inode of different type */ if ((inode->i_mode & S_IFMT) != (fattr->cf_mode & S_IFMT)) return 0; |
5acfec250 cifs: reduce fals... |
897 |
/* if it's not a directory or has no dentries, then flag it */ |
b3d9b7a3c vfs: switch i_den... |
898 |
if (S_ISDIR(inode->i_mode) && !hlist_empty(&inode->i_dentry)) |
3d6943803 cifs: guard again... |
899 |
fattr->cf_flags |= CIFS_FATTR_INO_COLLISION; |
3d6943803 cifs: guard again... |
900 |
|
cc0bad755 cifs: add new cif... |
901 902 903 904 905 906 907 908 909 |
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... |
910 |
CIFS_I(inode)->createtime = fattr->cf_createtime; |
cc0bad755 cifs: add new cif... |
911 912 |
return 0; } |
5acfec250 cifs: reduce fals... |
913 914 915 916 917 918 919 920 921 |
/* * 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... |
922 |
spin_lock(&inode->i_lock); |
946e51f2b move d_rcu from o... |
923 |
hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) { |
5acfec250 cifs: reduce fals... |
924 |
if (!d_unhashed(dentry) || IS_ROOT(dentry)) { |
873feea09 fs: dcache per-in... |
925 |
spin_unlock(&inode->i_lock); |
5acfec250 cifs: reduce fals... |
926 927 928 |
return true; } } |
873feea09 fs: dcache per-in... |
929 |
spin_unlock(&inode->i_lock); |
5acfec250 cifs: reduce fals... |
930 931 |
return false; } |
cc0bad755 cifs: add new cif... |
932 933 934 935 936 937 |
/* 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... |
938 |
retry_iget5_locked: |
f96637be0 [CIFS] cifs: Rena... |
939 940 |
cifs_dbg(FYI, "looking for uniqueid=%llu ", fattr->cf_uniqueid); |
cc0bad755 cifs: add new cif... |
941 942 943 944 945 |
/* 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... |
946 |
if (inode) { |
5acfec250 cifs: reduce fals... |
947 |
/* was there a potentially problematic inode collision? */ |
3d6943803 cifs: guard again... |
948 |
if (fattr->cf_flags & CIFS_FATTR_INO_COLLISION) { |
3d6943803 cifs: guard again... |
949 |
fattr->cf_flags &= ~CIFS_FATTR_INO_COLLISION; |
5acfec250 cifs: reduce fals... |
950 951 952 953 954 955 956 |
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... |
957 |
} |
cc0bad755 cifs: add new cif... |
958 959 960 961 962 |
cifs_fattr_to_inode(inode, fattr); if (sb->s_flags & MS_NOATIME) inode->i_flags |= S_NOATIME | S_NOCMTIME; if (inode->i_state & I_NEW) { inode->i_ino = hash; |
0ccd48025 [CIFS] Missing ifdef |
963 |
#ifdef CONFIG_CIFS_FSCACHE |
9451a9a52 cifs: define inod... |
964 965 |
/* initialize per-inode cache cookie pointer */ CIFS_I(inode)->fscache = NULL; |
0ccd48025 [CIFS] Missing ifdef |
966 |
#endif |
cc0bad755 cifs: add new cif... |
967 968 969 970 971 972 |
unlock_new_inode(inode); } } return inode; } |
1da177e4c Linux-2.6.12-rc2 |
973 |
/* gets root inode */ |
9b6763e0a cifs: Remove unus... |
974 |
struct inode *cifs_root_iget(struct super_block *sb) |
1da177e4c Linux-2.6.12-rc2 |
975 |
{ |
6d5786a34 CIFS: Rename Get/... |
976 |
unsigned int xid; |
0d424ad0a cifs: add cifs_sb... |
977 |
struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
cc0bad755 cifs: add new cif... |
978 |
struct inode *inode = NULL; |
ce634ab28 iget: stop CIFS f... |
979 |
long rc; |
96daf2b09 [CIFS] Rename thr... |
980 |
struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); |
a6b5058fa fs/cifs: make sha... |
981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 |
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... |
997 |
|
6d5786a34 CIFS: Rename Get/... |
998 |
xid = get_xid(); |
b5b374eab Workaround Mac se... |
999 |
if (tcon->unix_ext) { |
a6b5058fa fs/cifs: make sha... |
1000 |
rc = cifs_get_inode_info_unix(&inode, path, sb, xid); |
b5b374eab Workaround Mac se... |
1001 1002 1003 1004 1005 1006 |
/* some servers mistakenly claim POSIX support */ if (rc != -EOPNOTSUPP) goto iget_no_retry; cifs_dbg(VFS, "server does not support POSIX extensions"); tcon->unix_ext = false; } |
a6b5058fa fs/cifs: make sha... |
1007 1008 |
convert_delimiter(path, CIFS_DIR_SEP(cifs_sb)); rc = cifs_get_inode_info(&inode, path, NULL, sb, xid, NULL); |
0b8f18e35 cifs: convert cif... |
1009 |
|
b5b374eab Workaround Mac se... |
1010 |
iget_no_retry: |
a7851ce73 cifs: fix another... |
1011 1012 1013 1014 |
if (!inode) { inode = ERR_PTR(rc); goto out; } |
cc0bad755 cifs: add new cif... |
1015 |
|
0ccd48025 [CIFS] Missing ifdef |
1016 |
#ifdef CONFIG_CIFS_FSCACHE |
d03382ce9 cifs: define supe... |
1017 |
/* populate tcon->resource_id */ |
0d424ad0a cifs: add cifs_sb... |
1018 |
tcon->resource_id = CIFS_I(inode)->uniqueid; |
0ccd48025 [CIFS] Missing ifdef |
1019 |
#endif |
d03382ce9 cifs: define supe... |
1020 |
|
0d424ad0a cifs: add cifs_sb... |
1021 |
if (rc && tcon->ipc) { |
f96637be0 [CIFS] cifs: Rena... |
1022 1023 |
cifs_dbg(FYI, "ipc connection - fake read inode "); |
b7ca69289 CIFS: Protect i_n... |
1024 |
spin_lock(&inode->i_lock); |
7f8ed420f [CIFS] CIFS suppo... |
1025 |
inode->i_mode |= S_IFDIR; |
bfe868486 filesystems: add ... |
1026 |
set_nlink(inode, 2); |
7f8ed420f [CIFS] CIFS suppo... |
1027 1028 1029 1030 |
inode->i_op = &cifs_ipc_inode_ops; inode->i_fop = &simple_dir_operations; inode->i_uid = cifs_sb->mnt_uid; inode->i_gid = cifs_sb->mnt_gid; |
b7ca69289 CIFS: Protect i_n... |
1031 |
spin_unlock(&inode->i_lock); |
ad661334b [CIFS] mount of I... |
1032 |
} else if (rc) { |
ce634ab28 iget: stop CIFS f... |
1033 |
iget_failed(inode); |
a7851ce73 cifs: fix another... |
1034 |
inode = ERR_PTR(rc); |
7f8ed420f [CIFS] CIFS suppo... |
1035 |
} |
a7851ce73 cifs: fix another... |
1036 |
out: |
a6b5058fa fs/cifs: make sha... |
1037 |
kfree(path); |
6d5786a34 CIFS: Rename Get/... |
1038 |
/* can not call macro free_xid here since in a void func |
ce634ab28 iget: stop CIFS f... |
1039 1040 |
* TODO: This is no longer true */ |
6d5786a34 CIFS: Rename Get/... |
1041 |
_free_xid(xid); |
ce634ab28 iget: stop CIFS f... |
1042 |
return inode; |
1da177e4c Linux-2.6.12-rc2 |
1043 |
} |
ed6875e0d CIFS: Move unlink... |
1044 |
int |
6d5786a34 CIFS: Rename Get/... |
1045 |
cifs_set_file_info(struct inode *inode, struct iattr *attrs, unsigned int xid, |
ed6875e0d CIFS: Move unlink... |
1046 |
char *full_path, __u32 dosattr) |
388e57b27 [CIFS] use common... |
1047 |
{ |
388e57b27 [CIFS] use common... |
1048 |
bool set_time = false; |
388e57b27 [CIFS] use common... |
1049 |
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
6bdf6dbd6 CIFS: Move set_fi... |
1050 |
struct TCP_Server_Info *server; |
388e57b27 [CIFS] use common... |
1051 |
FILE_BASIC_INFO info_buf; |
1adcb7109 [CIFS] add extra ... |
1052 1053 |
if (attrs == NULL) return -EINVAL; |
6bdf6dbd6 CIFS: Move set_fi... |
1054 1055 1056 |
server = cifs_sb_master_tcon(cifs_sb)->ses->server; if (!server->ops->set_file_info) return -ENOSYS; |
388e57b27 [CIFS] use common... |
1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 |
if (attrs->ia_valid & ATTR_ATIME) { set_time = true; info_buf.LastAccessTime = cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_atime)); } else info_buf.LastAccessTime = 0; if (attrs->ia_valid & ATTR_MTIME) { set_time = true; info_buf.LastWriteTime = cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_mtime)); } 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... |
1078 1079 |
cifs_dbg(FYI, "CIFS - CTIME changed "); |
388e57b27 [CIFS] use common... |
1080 1081 1082 1083 1084 1085 1086 |
info_buf.ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_ctime)); } else info_buf.ChangeTime = 0; info_buf.CreationTime = 0; /* don't change */ info_buf.Attributes = cpu_to_le32(dosattr); |
6bdf6dbd6 CIFS: Move set_fi... |
1087 |
return server->ops->set_file_info(inode, full_path, &info_buf, xid); |
388e57b27 [CIFS] use common... |
1088 |
} |
a12a1ac7a cifs: move rename... |
1089 |
/* |
ed6875e0d CIFS: Move unlink... |
1090 |
* Open the given file (if it isn't already), set the DELETE_ON_CLOSE bit |
a12a1ac7a cifs: move rename... |
1091 1092 1093 |
* and rename it to a random name that hopefully won't conflict with * anything else. */ |
ed6875e0d CIFS: Move unlink... |
1094 1095 1096 |
int cifs_rename_pending_delete(const char *full_path, struct dentry *dentry, const unsigned int xid) |
a12a1ac7a cifs: move rename... |
1097 1098 1099 |
{ int oplock = 0; int rc; |
d81b8a40e CIFS: Cleanup cif... |
1100 1101 |
struct cifs_fid fid; struct cifs_open_parms oparms; |
2b0143b5c VFS: normal files... |
1102 |
struct inode *inode = d_inode(dentry); |
a12a1ac7a cifs: move rename... |
1103 1104 |
struct cifsInodeInfo *cifsInode = CIFS_I(inode); struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
7ffec3724 cifs: add refcoun... |
1105 |
struct tcon_link *tlink; |
96daf2b09 [CIFS] Rename thr... |
1106 |
struct cifs_tcon *tcon; |
3270958b7 [CIFS] undo chang... |
1107 1108 |
__u32 dosattr, origattr; FILE_BASIC_INFO *info_buf = NULL; |
a12a1ac7a cifs: move rename... |
1109 |
|
7ffec3724 cifs: add refcoun... |
1110 1111 1112 1113 |
tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) return PTR_ERR(tlink); tcon = tlink_tcon(tlink); |
c483a9841 cifs: Check serve... |
1114 1115 1116 1117 1118 1119 1120 1121 |
/* * 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... |
1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 |
oparms.tcon = tcon; oparms.cifs_sb = cifs_sb; oparms.desired_access = DELETE | FILE_WRITE_ATTRIBUTES; oparms.create_options = CREATE_NOT_DIR; 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... |
1132 1133 |
if (rc != 0) goto out; |
3270958b7 [CIFS] undo chang... |
1134 1135 1136 1137 1138 |
origattr = cifsInode->cifsAttrs; if (origattr == 0) origattr |= ATTR_NORMAL; dosattr = origattr & ~ATTR_READONLY; |
a12a1ac7a cifs: move rename... |
1139 1140 1141 |
if (dosattr == 0) dosattr |= ATTR_NORMAL; dosattr |= ATTR_HIDDEN; |
3270958b7 [CIFS] undo chang... |
1142 1143 1144 1145 1146 1147 1148 1149 |
/* 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... |
1150 |
rc = CIFSSMBSetFileInfo(xid, tcon, info_buf, fid.netfid, |
3270958b7 [CIFS] undo chang... |
1151 1152 1153 |
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... |
1154 |
if (!rc) |
3270958b7 [CIFS] undo chang... |
1155 1156 1157 |
cifsInode->cifsAttrs = dosattr; else dosattr = origattr; /* since not able to change them */ |
a12a1ac7a cifs: move rename... |
1158 |
} |
a12a1ac7a cifs: move rename... |
1159 |
|
dd1db2ded cifs: don't use C... |
1160 |
/* rename the file */ |
d81b8a40e CIFS: Cleanup cif... |
1161 1162 |
rc = CIFSSMBRenameOpenFile(xid, tcon, fid.netfid, NULL, cifs_sb->local_nls, |
2baa26825 Remap reserved po... |
1163 |
cifs_remap(cifs_sb)); |
3270958b7 [CIFS] undo chang... |
1164 |
if (rc != 0) { |
47c78f4a7 cifs: map NT_STAT... |
1165 |
rc = -EBUSY; |
3270958b7 [CIFS] undo chang... |
1166 1167 |
goto undo_setattr; } |
6d22f0989 cifs: add functio... |
1168 |
|
3270958b7 [CIFS] undo chang... |
1169 |
/* try to set DELETE_ON_CLOSE */ |
aff8d5ca7 cifs: convert boo... |
1170 |
if (!test_bit(CIFS_INO_DELETE_PENDING, &cifsInode->flags)) { |
d81b8a40e CIFS: Cleanup cif... |
1171 |
rc = CIFSSMBSetFileDisposition(xid, tcon, true, fid.netfid, |
3270958b7 [CIFS] undo chang... |
1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 |
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... |
1184 |
rc = -EBUSY; |
3270958b7 [CIFS] undo chang... |
1185 1186 |
goto undo_rename; } |
aff8d5ca7 cifs: convert boo... |
1187 |
set_bit(CIFS_INO_DELETE_PENDING, &cifsInode->flags); |
3270958b7 [CIFS] undo chang... |
1188 |
} |
7ce86d5a9 cifs: work around... |
1189 |
|
a12a1ac7a cifs: move rename... |
1190 |
out_close: |
d81b8a40e CIFS: Cleanup cif... |
1191 |
CIFSSMBClose(xid, tcon, fid.netfid); |
a12a1ac7a cifs: move rename... |
1192 |
out: |
3270958b7 [CIFS] undo chang... |
1193 |
kfree(info_buf); |
7ffec3724 cifs: add refcoun... |
1194 |
cifs_put_tlink(tlink); |
a12a1ac7a cifs: move rename... |
1195 |
return rc; |
3270958b7 [CIFS] undo chang... |
1196 1197 1198 1199 1200 1201 1202 |
/* * 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... |
1203 |
CIFSSMBRenameOpenFile(xid, tcon, fid.netfid, dentry->d_name.name, |
2baa26825 Remap reserved po... |
1204 |
cifs_sb->local_nls, cifs_remap(cifs_sb)); |
3270958b7 [CIFS] undo chang... |
1205 1206 1207 |
undo_setattr: if (dosattr != origattr) { info_buf->Attributes = cpu_to_le32(origattr); |
d81b8a40e CIFS: Cleanup cif... |
1208 |
if (!CIFSSMBSetFileInfo(xid, tcon, info_buf, fid.netfid, |
3270958b7 [CIFS] undo chang... |
1209 1210 1211 1212 1213 |
current->tgid)) cifsInode->cifsAttrs = origattr; } goto out_close; |
a12a1ac7a cifs: move rename... |
1214 |
} |
b7ca69289 CIFS: Protect i_n... |
1215 1216 1217 1218 1219 1220 1221 1222 1223 |
/* 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_... |
1224 1225 |
/* |
2b0143b5c VFS: normal files... |
1226 |
* If d_inode(dentry) is null (usually meaning the cached dentry |
ff6945279 [CIFS] Make cifs_... |
1227 |
* is a negative dentry) then we would attempt a standard SMB delete, but |
af901ca18 tree-wide: fix as... |
1228 1229 |
* if that fails we can not attempt the fall back mechanisms on EACCESS * but will return the EACCESS to the caller. Note that the VFS does not call |
ff6945279 [CIFS] Make cifs_... |
1230 1231 |
* unlink on negative dentries currently. */ |
5f0319a79 cifs: clean up va... |
1232 |
int cifs_unlink(struct inode *dir, struct dentry *dentry) |
1da177e4c Linux-2.6.12-rc2 |
1233 1234 |
{ int rc = 0; |
6d5786a34 CIFS: Rename Get/... |
1235 |
unsigned int xid; |
1da177e4c Linux-2.6.12-rc2 |
1236 |
char *full_path = NULL; |
2b0143b5c VFS: normal files... |
1237 |
struct inode *inode = d_inode(dentry); |
ff6945279 [CIFS] Make cifs_... |
1238 |
struct cifsInodeInfo *cifs_inode; |
5f0319a79 cifs: clean up va... |
1239 1240 |
struct super_block *sb = dir->i_sb; struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
7ffec3724 cifs: add refcoun... |
1241 |
struct tcon_link *tlink; |
96daf2b09 [CIFS] Rename thr... |
1242 |
struct cifs_tcon *tcon; |
ed6875e0d CIFS: Move unlink... |
1243 |
struct TCP_Server_Info *server; |
6050247d8 [CIFS] clean up ... |
1244 1245 |
struct iattr *attrs = NULL; __u32 dosattr = 0, origattr = 0; |
1da177e4c Linux-2.6.12-rc2 |
1246 |
|
f96637be0 [CIFS] cifs: Rena... |
1247 1248 |
cifs_dbg(FYI, "cifs_unlink, dir=0x%p, dentry=0x%p ", dir, dentry); |
1da177e4c Linux-2.6.12-rc2 |
1249 |
|
7ffec3724 cifs: add refcoun... |
1250 1251 1252 1253 |
tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) return PTR_ERR(tlink); tcon = tlink_tcon(tlink); |
ed6875e0d CIFS: Move unlink... |
1254 |
server = tcon->ses->server; |
7ffec3724 cifs: add refcoun... |
1255 |
|
6d5786a34 CIFS: Rename Get/... |
1256 |
xid = get_xid(); |
1da177e4c Linux-2.6.12-rc2 |
1257 |
|
5f0319a79 cifs: clean up va... |
1258 1259 1260 |
/* Unlink can be called from rename so we can not take the * sb->s_vfs_rename_mutex here */ full_path = build_path_from_dentry(dentry); |
1da177e4c Linux-2.6.12-rc2 |
1261 |
if (full_path == NULL) { |
0f3bc09ee cifs: Fix incorre... |
1262 |
rc = -ENOMEM; |
7ffec3724 cifs: add refcoun... |
1263 |
goto unlink_out; |
1da177e4c Linux-2.6.12-rc2 |
1264 |
} |
2d785a50a [CIFS] Add suppor... |
1265 |
|
29e20f9c6 CIFS: Make CAP_* ... |
1266 1267 |
if (cap_unix(tcon->ses) && (CIFS_UNIX_POSIX_PATH_OPS_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability))) { |
5f0319a79 cifs: clean up va... |
1268 |
rc = CIFSPOSIXDelFile(xid, tcon, full_path, |
2d785a50a [CIFS] Add suppor... |
1269 |
SMB_POSIX_UNLINK_FILE_TARGET, cifs_sb->local_nls, |
2baa26825 Remap reserved po... |
1270 |
cifs_remap(cifs_sb)); |
f96637be0 [CIFS] cifs: Rena... |
1271 1272 |
cifs_dbg(FYI, "posix del rc %d ", rc); |
2d785a50a [CIFS] Add suppor... |
1273 1274 1275 |
if ((rc == 0) || (rc == -ENOENT)) goto psx_del_no_retry; } |
1da177e4c Linux-2.6.12-rc2 |
1276 |
|
6050247d8 [CIFS] clean up ... |
1277 |
retry_std_delete: |
ed6875e0d CIFS: Move unlink... |
1278 1279 1280 1281 1282 1283 |
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 ... |
1284 |
|
2d785a50a [CIFS] Add suppor... |
1285 |
psx_del_no_retry: |
1da177e4c Linux-2.6.12-rc2 |
1286 |
if (!rc) { |
5f0319a79 cifs: clean up va... |
1287 |
if (inode) |
b7ca69289 CIFS: Protect i_n... |
1288 |
cifs_drop_nlink(inode); |
1da177e4c Linux-2.6.12-rc2 |
1289 |
} else if (rc == -ENOENT) { |
5f0319a79 cifs: clean up va... |
1290 |
d_drop(dentry); |
47c78f4a7 cifs: map NT_STAT... |
1291 |
} else if (rc == -EBUSY) { |
ed6875e0d CIFS: Move unlink... |
1292 1293 1294 1295 1296 1297 |
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_... |
1298 |
} else if ((rc == -EACCES) && (dosattr == 0) && inode) { |
388e57b27 [CIFS] use common... |
1299 1300 1301 1302 |
attrs = kzalloc(sizeof(*attrs), GFP_KERNEL); if (attrs == NULL) { rc = -ENOMEM; goto out_reval; |
1da177e4c Linux-2.6.12-rc2 |
1303 |
} |
388e57b27 [CIFS] use common... |
1304 1305 |
/* try to reset dos attributes */ |
ff6945279 [CIFS] Make cifs_... |
1306 1307 |
cifs_inode = CIFS_I(inode); origattr = cifs_inode->cifsAttrs; |
6050247d8 [CIFS] clean up ... |
1308 1309 1310 |
if (origattr == 0) origattr |= ATTR_NORMAL; dosattr = origattr & ~ATTR_READONLY; |
388e57b27 [CIFS] use common... |
1311 1312 1313 1314 1315 |
if (dosattr == 0) dosattr |= ATTR_NORMAL; dosattr |= ATTR_HIDDEN; rc = cifs_set_file_info(inode, attrs, xid, full_path, dosattr); |
388e57b27 [CIFS] use common... |
1316 1317 |
if (rc != 0) goto out_reval; |
6050247d8 [CIFS] clean up ... |
1318 1319 |
goto retry_std_delete; |
1da177e4c Linux-2.6.12-rc2 |
1320 |
} |
6050247d8 [CIFS] clean up ... |
1321 1322 1323 1324 |
/* 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... |
1325 |
out_reval: |
4523cc304 [CIFS] UID/GID ov... |
1326 |
if (inode) { |
ff6945279 [CIFS] Make cifs_... |
1327 1328 |
cifs_inode = CIFS_I(inode); cifs_inode->time = 0; /* will force revalidate to get info |
5f0319a79 cifs: clean up va... |
1329 1330 |
when needed */ inode->i_ctime = current_fs_time(sb); |
06bcfedd0 [CIFS] Fix typo i... |
1331 |
} |
5f0319a79 cifs: clean up va... |
1332 |
dir->i_ctime = dir->i_mtime = current_fs_time(sb); |
ff6945279 [CIFS] Make cifs_... |
1333 |
cifs_inode = CIFS_I(dir); |
6050247d8 [CIFS] clean up ... |
1334 |
CIFS_I(dir)->time = 0; /* force revalidate of dir as well */ |
7ffec3724 cifs: add refcoun... |
1335 |
unlink_out: |
1da177e4c Linux-2.6.12-rc2 |
1336 |
kfree(full_path); |
6050247d8 [CIFS] clean up ... |
1337 |
kfree(attrs); |
6d5786a34 CIFS: Rename Get/... |
1338 |
free_xid(xid); |
7ffec3724 cifs: add refcoun... |
1339 |
cifs_put_tlink(tlink); |
1da177e4c Linux-2.6.12-rc2 |
1340 1341 |
return rc; } |
ff691e969 CIFS: Simplify ci... |
1342 |
static int |
101b92d95 cifs: cleanups fo... |
1343 |
cifs_mkdir_qinfo(struct inode *parent, struct dentry *dentry, umode_t mode, |
ff691e969 CIFS: Simplify ci... |
1344 1345 1346 1347 |
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... |
1348 |
struct inode *inode = NULL; |
ff691e969 CIFS: Simplify ci... |
1349 1350 |
if (tcon->unix_ext) |
101b92d95 cifs: cleanups fo... |
1351 |
rc = cifs_get_inode_info_unix(&inode, full_path, parent->i_sb, |
ff691e969 CIFS: Simplify ci... |
1352 1353 |
xid); else |
101b92d95 cifs: cleanups fo... |
1354 1355 |
rc = cifs_get_inode_info(&inode, full_path, NULL, parent->i_sb, xid, NULL); |
ff691e969 CIFS: Simplify ci... |
1356 1357 |
if (rc) return rc; |
ff691e969 CIFS: Simplify ci... |
1358 1359 |
/* * setting nlink not necessary except in cases where we failed to get it |
101b92d95 cifs: cleanups fo... |
1360 1361 |
* 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... |
1362 |
*/ |
101b92d95 cifs: cleanups fo... |
1363 1364 |
if (inode->i_nlink < 2) set_nlink(inode, 2); |
ff691e969 CIFS: Simplify ci... |
1365 1366 |
mode &= ~current_umask(); /* must turn on setgid bit if parent dir has it */ |
101b92d95 cifs: cleanups fo... |
1367 |
if (parent->i_mode & S_ISGID) |
ff691e969 CIFS: Simplify ci... |
1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 |
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... |
1379 |
args.uid = current_fsuid(); |
101b92d95 cifs: cleanups fo... |
1380 |
if (parent->i_mode & S_ISGID) |
49418b2c2 cifs: Modify stru... |
1381 |
args.gid = parent->i_gid; |
ff691e969 CIFS: Simplify ci... |
1382 |
else |
49418b2c2 cifs: Modify stru... |
1383 |
args.gid = current_fsgid(); |
ff691e969 CIFS: Simplify ci... |
1384 |
} else { |
49418b2c2 cifs: Modify stru... |
1385 1386 |
args.uid = INVALID_UID; /* no change */ args.gid = INVALID_GID; /* no change */ |
ff691e969 CIFS: Simplify ci... |
1387 1388 1389 |
} CIFSSMBUnixSetPathInfo(xid, tcon, full_path, &args, cifs_sb->local_nls, |
2baa26825 Remap reserved po... |
1390 |
cifs_remap(cifs_sb)); |
ff691e969 CIFS: Simplify ci... |
1391 |
} else { |
f436720e9 CIFS: Separate pr... |
1392 |
struct TCP_Server_Info *server = tcon->ses->server; |
ff691e969 CIFS: Simplify ci... |
1393 |
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) && |
f436720e9 CIFS: Separate pr... |
1394 |
(mode & S_IWUGO) == 0 && server->ops->mkdir_setinfo) |
101b92d95 cifs: cleanups fo... |
1395 |
server->ops->mkdir_setinfo(inode, full_path, cifs_sb, |
f436720e9 CIFS: Separate pr... |
1396 |
tcon, xid); |
101b92d95 cifs: cleanups fo... |
1397 1398 1399 1400 1401 1402 1403 1404 1405 |
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... |
1406 1407 |
} } |
101b92d95 cifs: cleanups fo... |
1408 |
d_instantiate(dentry, inode); |
ff691e969 CIFS: Simplify ci... |
1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 |
return rc; } 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... |
1432 |
cifs_sb->local_nls, cifs_remap(cifs_sb)); |
ff691e969 CIFS: Simplify ci... |
1433 1434 1435 |
if (rc == -EOPNOTSUPP) goto posix_mkdir_out; else if (rc) { |
f96637be0 [CIFS] cifs: Rena... |
1436 1437 |
cifs_dbg(FYI, "posix mkdir returned 0x%x ", rc); |
ff691e969 CIFS: Simplify ci... |
1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 |
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... |
1459 1460 1461 |
cifs_dbg(FYI, "instantiated dentry %p %pd to inode %p ", dentry, dentry, newinode); |
ff691e969 CIFS: Simplify ci... |
1462 1463 |
if (newinode->i_nlink != 2) |
f96637be0 [CIFS] cifs: Rena... |
1464 1465 1466 |
cifs_dbg(FYI, "unexpected number of links %d ", newinode->i_nlink); |
ff691e969 CIFS: Simplify ci... |
1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 |
#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; } |
18bb1db3e switch vfs_mkdir(... |
1477 |
int cifs_mkdir(struct inode *inode, struct dentry *direntry, umode_t mode) |
1da177e4c Linux-2.6.12-rc2 |
1478 |
{ |
ff691e969 CIFS: Simplify ci... |
1479 |
int rc = 0; |
6d5786a34 CIFS: Rename Get/... |
1480 |
unsigned int xid; |
1da177e4c Linux-2.6.12-rc2 |
1481 |
struct cifs_sb_info *cifs_sb; |
7ffec3724 cifs: add refcoun... |
1482 |
struct tcon_link *tlink; |
29e20f9c6 CIFS: Make CAP_* ... |
1483 |
struct cifs_tcon *tcon; |
f436720e9 CIFS: Separate pr... |
1484 |
struct TCP_Server_Info *server; |
ff691e969 CIFS: Simplify ci... |
1485 |
char *full_path; |
1da177e4c Linux-2.6.12-rc2 |
1486 |
|
f96637be0 [CIFS] cifs: Rena... |
1487 1488 1489 |
cifs_dbg(FYI, "In cifs_mkdir, mode = 0x%hx inode = 0x%p ", mode, inode); |
1da177e4c Linux-2.6.12-rc2 |
1490 |
|
1da177e4c Linux-2.6.12-rc2 |
1491 |
cifs_sb = CIFS_SB(inode->i_sb); |
7ffec3724 cifs: add refcoun... |
1492 1493 1494 |
tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) return PTR_ERR(tlink); |
29e20f9c6 CIFS: Make CAP_* ... |
1495 |
tcon = tlink_tcon(tlink); |
7ffec3724 cifs: add refcoun... |
1496 |
|
6d5786a34 CIFS: Rename Get/... |
1497 |
xid = get_xid(); |
1da177e4c Linux-2.6.12-rc2 |
1498 |
|
7f57356b7 [CIFS] Remove cif... |
1499 |
full_path = build_path_from_dentry(direntry); |
1da177e4c Linux-2.6.12-rc2 |
1500 |
if (full_path == NULL) { |
0f3bc09ee cifs: Fix incorre... |
1501 |
rc = -ENOMEM; |
7ffec3724 cifs: add refcoun... |
1502 |
goto mkdir_out; |
1da177e4c Linux-2.6.12-rc2 |
1503 |
} |
50c2f7538 [CIFS] whitespace... |
1504 |
|
29e20f9c6 CIFS: Make CAP_* ... |
1505 1506 |
if (cap_unix(tcon->ses) && (CIFS_UNIX_POSIX_PATH_OPS_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability))) { |
ff691e969 CIFS: Simplify ci... |
1507 1508 1509 |
rc = cifs_posix_mkdir(inode, direntry, mode, full_path, cifs_sb, tcon, xid); if (rc != -EOPNOTSUPP) |
2dd29d313 [CIFS] New CIFS P... |
1510 |
goto mkdir_out; |
fb8c4b14d [CIFS] whitespace... |
1511 |
} |
ff691e969 CIFS: Simplify ci... |
1512 |
|
f436720e9 CIFS: Separate pr... |
1513 1514 1515 1516 1517 1518 |
server = tcon->ses->server; if (!server->ops->mkdir) { rc = -ENOSYS; goto mkdir_out; } |
1da177e4c Linux-2.6.12-rc2 |
1519 |
/* BB add setting the equivalent of mode via CreateX w/ACLs */ |
f436720e9 CIFS: Separate pr... |
1520 |
rc = server->ops->mkdir(xid, tcon, full_path, cifs_sb); |
1da177e4c Linux-2.6.12-rc2 |
1521 |
if (rc) { |
f96637be0 [CIFS] cifs: Rena... |
1522 1523 |
cifs_dbg(FYI, "cifs_mkdir returned 0x%x ", rc); |
1da177e4c Linux-2.6.12-rc2 |
1524 |
d_drop(direntry); |
ff691e969 CIFS: Simplify ci... |
1525 |
goto mkdir_out; |
1da177e4c Linux-2.6.12-rc2 |
1526 |
} |
ff691e969 CIFS: Simplify ci... |
1527 1528 1529 |
rc = cifs_mkdir_qinfo(inode, direntry, mode, full_path, cifs_sb, tcon, xid); |
fb8c4b14d [CIFS] whitespace... |
1530 |
mkdir_out: |
6de2ce423 CIFS: Fix mkdir/r... |
1531 1532 1533 1534 1535 |
/* * Force revalidate to get parent dir info when needed since cached * attributes are invalid now. */ CIFS_I(inode)->time = 0; |
1da177e4c Linux-2.6.12-rc2 |
1536 |
kfree(full_path); |
6d5786a34 CIFS: Rename Get/... |
1537 |
free_xid(xid); |
7ffec3724 cifs: add refcoun... |
1538 |
cifs_put_tlink(tlink); |
1da177e4c Linux-2.6.12-rc2 |
1539 1540 1541 1542 1543 1544 |
return rc; } int cifs_rmdir(struct inode *inode, struct dentry *direntry) { int rc = 0; |
6d5786a34 CIFS: Rename Get/... |
1545 |
unsigned int xid; |
1da177e4c Linux-2.6.12-rc2 |
1546 |
struct cifs_sb_info *cifs_sb; |
7ffec3724 cifs: add refcoun... |
1547 |
struct tcon_link *tlink; |
f958ca5d8 CIFS: Move rmdir ... |
1548 1549 |
struct cifs_tcon *tcon; struct TCP_Server_Info *server; |
1da177e4c Linux-2.6.12-rc2 |
1550 1551 |
char *full_path = NULL; struct cifsInodeInfo *cifsInode; |
f96637be0 [CIFS] cifs: Rena... |
1552 1553 |
cifs_dbg(FYI, "cifs_rmdir, inode = 0x%p ", inode); |
1da177e4c Linux-2.6.12-rc2 |
1554 |
|
6d5786a34 CIFS: Rename Get/... |
1555 |
xid = get_xid(); |
1da177e4c Linux-2.6.12-rc2 |
1556 |
|
7f57356b7 [CIFS] Remove cif... |
1557 |
full_path = build_path_from_dentry(direntry); |
1da177e4c Linux-2.6.12-rc2 |
1558 |
if (full_path == NULL) { |
0f3bc09ee cifs: Fix incorre... |
1559 |
rc = -ENOMEM; |
7ffec3724 cifs: add refcoun... |
1560 |
goto rmdir_exit; |
1da177e4c Linux-2.6.12-rc2 |
1561 |
} |
7ffec3724 cifs: add refcoun... |
1562 1563 1564 1565 1566 1567 |
cifs_sb = CIFS_SB(inode->i_sb); tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) { rc = PTR_ERR(tlink); goto rmdir_exit; } |
f958ca5d8 CIFS: Move rmdir ... |
1568 1569 1570 1571 1572 1573 1574 1575 |
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... |
1576 |
|
f958ca5d8 CIFS: Move rmdir ... |
1577 |
rc = server->ops->rmdir(xid, tcon, full_path, cifs_sb); |
7ffec3724 cifs: add refcoun... |
1578 |
cifs_put_tlink(tlink); |
1da177e4c Linux-2.6.12-rc2 |
1579 1580 |
if (!rc) { |
2b0143b5c VFS: normal files... |
1581 1582 1583 1584 |
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 |
1585 |
} |
2b0143b5c VFS: normal files... |
1586 |
cifsInode = CIFS_I(d_inode(direntry)); |
6de2ce423 CIFS: Fix mkdir/r... |
1587 1588 |
/* force revalidate to go get info when needed */ cifsInode->time = 0; |
42c245447 [CIFS] revalidate... |
1589 1590 |
cifsInode = CIFS_I(inode); |
6de2ce423 CIFS: Fix mkdir/r... |
1591 1592 1593 1594 1595 |
/* * Force revalidate to get parent dir info when needed since cached * attributes are invalid now. */ cifsInode->time = 0; |
42c245447 [CIFS] revalidate... |
1596 |
|
2b0143b5c VFS: normal files... |
1597 |
d_inode(direntry)->i_ctime = inode->i_ctime = inode->i_mtime = |
1da177e4c Linux-2.6.12-rc2 |
1598 |
current_fs_time(inode->i_sb); |
7ffec3724 cifs: add refcoun... |
1599 |
rmdir_exit: |
1da177e4c Linux-2.6.12-rc2 |
1600 |
kfree(full_path); |
6d5786a34 CIFS: Rename Get/... |
1601 |
free_xid(xid); |
1da177e4c Linux-2.6.12-rc2 |
1602 1603 |
return rc; } |
ee2fd967f [CIFS] fix busy-... |
1604 |
static int |
8ceb98437 CIFS: Move rename... |
1605 1606 1607 |
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-... |
1608 1609 |
{ struct cifs_sb_info *cifs_sb = CIFS_SB(from_dentry->d_sb); |
7ffec3724 cifs: add refcoun... |
1610 |
struct tcon_link *tlink; |
8ceb98437 CIFS: Move rename... |
1611 1612 |
struct cifs_tcon *tcon; struct TCP_Server_Info *server; |
d81b8a40e CIFS: Cleanup cif... |
1613 1614 |
struct cifs_fid fid; struct cifs_open_parms oparms; |
ee2fd967f [CIFS] fix busy-... |
1615 |
int oplock, rc; |
7ffec3724 cifs: add refcoun... |
1616 1617 1618 |
tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) return PTR_ERR(tlink); |
8ceb98437 CIFS: Move rename... |
1619 1620 1621 1622 1623 |
tcon = tlink_tcon(tlink); server = tcon->ses->server; if (!server->ops->rename) return -ENOSYS; |
7ffec3724 cifs: add refcoun... |
1624 |
|
ee2fd967f [CIFS] fix busy-... |
1625 |
/* try path-based rename first */ |
8ceb98437 CIFS: Move rename... |
1626 |
rc = server->ops->rename(xid, tcon, from_path, to_path, cifs_sb); |
ee2fd967f [CIFS] fix busy-... |
1627 1628 |
/* |
8ceb98437 CIFS: Move rename... |
1629 1630 |
* 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-... |
1631 1632 |
* rename by filehandle to various Windows servers. */ |
47c78f4a7 cifs: map NT_STAT... |
1633 |
if (rc == 0 || rc != -EBUSY) |
7ffec3724 cifs: add refcoun... |
1634 |
goto do_rename_exit; |
ee2fd967f [CIFS] fix busy-... |
1635 |
|
ed0e3ace5 cifs: don't attem... |
1636 1637 |
/* open-file renames don't work across directories */ if (to_dentry->d_parent != from_dentry->d_parent) |
7ffec3724 cifs: add refcoun... |
1638 |
goto do_rename_exit; |
ed0e3ace5 cifs: don't attem... |
1639 |
|
d81b8a40e CIFS: Cleanup cif... |
1640 1641 |
oparms.tcon = tcon; oparms.cifs_sb = cifs_sb; |
ee2fd967f [CIFS] fix busy-... |
1642 |
/* open the file to be renamed -- we need DELETE perms */ |
d81b8a40e CIFS: Cleanup cif... |
1643 1644 1645 1646 1647 1648 1649 1650 |
oparms.desired_access = DELETE; oparms.create_options = CREATE_NOT_DIR; 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-... |
1651 |
if (rc == 0) { |
d81b8a40e CIFS: Cleanup cif... |
1652 |
rc = CIFSSMBRenameOpenFile(xid, tcon, fid.netfid, |
ee2fd967f [CIFS] fix busy-... |
1653 |
(const char *) to_dentry->d_name.name, |
2baa26825 Remap reserved po... |
1654 |
cifs_sb->local_nls, cifs_remap(cifs_sb)); |
d81b8a40e CIFS: Cleanup cif... |
1655 |
CIFSSMBClose(xid, tcon, fid.netfid); |
ee2fd967f [CIFS] fix busy-... |
1656 |
} |
7ffec3724 cifs: add refcoun... |
1657 1658 |
do_rename_exit: cifs_put_tlink(tlink); |
ee2fd967f [CIFS] fix busy-... |
1659 1660 |
return rc; } |
8ceb98437 CIFS: Move rename... |
1661 |
int |
7c33d5972 cifs: support REN... |
1662 1663 1664 |
cifs_rename2(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 |
1665 |
{ |
8ceb98437 CIFS: Move rename... |
1666 1667 |
char *from_name = NULL; char *to_name = NULL; |
639e7a913 cifs: eliminate r... |
1668 |
struct cifs_sb_info *cifs_sb; |
7ffec3724 cifs: add refcoun... |
1669 |
struct tcon_link *tlink; |
96daf2b09 [CIFS] Rename thr... |
1670 |
struct cifs_tcon *tcon; |
ee2fd967f [CIFS] fix busy-... |
1671 1672 |
FILE_UNIX_BASIC_INFO *info_buf_source = NULL; FILE_UNIX_BASIC_INFO *info_buf_target; |
6d5786a34 CIFS: Rename Get/... |
1673 1674 |
unsigned int xid; int rc, tmprc; |
1da177e4c Linux-2.6.12-rc2 |
1675 |
|
7c33d5972 cifs: support REN... |
1676 1677 |
if (flags & ~RENAME_NOREPLACE) return -EINVAL; |
639e7a913 cifs: eliminate r... |
1678 |
cifs_sb = CIFS_SB(source_dir->i_sb); |
7ffec3724 cifs: add refcoun... |
1679 1680 1681 1682 |
tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) return PTR_ERR(tlink); tcon = tlink_tcon(tlink); |
1da177e4c Linux-2.6.12-rc2 |
1683 |
|
6d5786a34 CIFS: Rename Get/... |
1684 |
xid = get_xid(); |
ee2fd967f [CIFS] fix busy-... |
1685 1686 |
/* |
ee2fd967f [CIFS] fix busy-... |
1687 1688 1689 |
* we already have the rename sem so we do not need to * grab it again here to protect the path integrity */ |
8ceb98437 CIFS: Move rename... |
1690 1691 |
from_name = build_path_from_dentry(source_dentry); if (from_name == NULL) { |
ee2fd967f [CIFS] fix busy-... |
1692 1693 1694 |
rc = -ENOMEM; goto cifs_rename_exit; } |
8ceb98437 CIFS: Move rename... |
1695 1696 |
to_name = build_path_from_dentry(target_dentry); if (to_name == NULL) { |
1da177e4c Linux-2.6.12-rc2 |
1697 1698 1699 |
rc = -ENOMEM; goto cifs_rename_exit; } |
8ceb98437 CIFS: Move rename... |
1700 1701 |
rc = cifs_do_rename(xid, source_dentry, from_name, target_dentry, to_name); |
ee2fd967f [CIFS] fix busy-... |
1702 |
|
7c33d5972 cifs: support REN... |
1703 1704 1705 1706 1707 |
/* * 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... |
1708 1709 |
if (rc == -EEXIST && tcon->unix_ext) { /* |
8ceb98437 CIFS: Move rename... |
1710 1711 |
* Are src and dst hardlinks of same inode? We can only tell * with unix extensions enabled. |
14121bdcc cifs: make cifs_r... |
1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 |
*/ info_buf_source = kmalloc(2 * sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL); if (info_buf_source == NULL) { rc = -ENOMEM; goto cifs_rename_exit; } info_buf_target = info_buf_source + 1; |
8ceb98437 CIFS: Move rename... |
1722 1723 1724 |
tmprc = CIFSSMBUnixQPathInfo(xid, tcon, from_name, info_buf_source, cifs_sb->local_nls, |
2baa26825 Remap reserved po... |
1725 |
cifs_remap(cifs_sb)); |
8d281efb6 cifs: fix unlinki... |
1726 |
if (tmprc != 0) |
14121bdcc cifs: make cifs_r... |
1727 |
goto unlink_target; |
ee2fd967f [CIFS] fix busy-... |
1728 |
|
8ceb98437 CIFS: Move rename... |
1729 1730 1731 |
tmprc = CIFSSMBUnixQPathInfo(xid, tcon, to_name, info_buf_target, cifs_sb->local_nls, |
2baa26825 Remap reserved po... |
1732 |
cifs_remap(cifs_sb)); |
14121bdcc cifs: make cifs_r... |
1733 |
|
8d281efb6 cifs: fix unlinki... |
1734 |
if (tmprc == 0 && (info_buf_source->UniqueId == |
ae6884a9d cifs: fix renamin... |
1735 |
info_buf_target->UniqueId)) { |
14121bdcc cifs: make cifs_r... |
1736 |
/* same file, POSIX says that this is a noop */ |
ae6884a9d cifs: fix renamin... |
1737 |
rc = 0; |
14121bdcc cifs: make cifs_r... |
1738 |
goto cifs_rename_exit; |
ae6884a9d cifs: fix renamin... |
1739 |
} |
8ceb98437 CIFS: Move rename... |
1740 1741 1742 1743 1744 |
} /* * else ... BB we could add the same check for Windows by * checking the UniqueId via FILE_INTERNAL_INFO */ |
14121bdcc cifs: make cifs_r... |
1745 |
|
ee2fd967f [CIFS] fix busy-... |
1746 |
unlink_target: |
fc6f39433 cifs: when renami... |
1747 |
/* Try unlinking the target dentry if it's not negative */ |
2b0143b5c VFS: normal files... |
1748 |
if (d_really_is_positive(target_dentry) && (rc == -EACCES || rc == -EEXIST)) { |
a07d32205 CIFS: Fix directo... |
1749 1750 1751 1752 |
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... |
1753 1754 |
if (tmprc) goto cifs_rename_exit; |
8ceb98437 CIFS: Move rename... |
1755 1756 |
rc = cifs_do_rename(xid, source_dentry, from_name, target_dentry, to_name); |
1da177e4c Linux-2.6.12-rc2 |
1757 |
} |
b46799a8f CIFS: Fix wrong d... |
1758 1759 1760 1761 1762 |
/* 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 = target_dir->i_mtime = current_fs_time(source_dir->i_sb); |
1da177e4c Linux-2.6.12-rc2 |
1763 |
cifs_rename_exit: |
ee2fd967f [CIFS] fix busy-... |
1764 |
kfree(info_buf_source); |
8ceb98437 CIFS: Move rename... |
1765 1766 |
kfree(from_name); kfree(to_name); |
6d5786a34 CIFS: Rename Get/... |
1767 |
free_xid(xid); |
7ffec3724 cifs: add refcoun... |
1768 |
cifs_put_tlink(tlink); |
1da177e4c Linux-2.6.12-rc2 |
1769 1770 |
return rc; } |
df2cf170c cifs: overhaul ci... |
1771 1772 |
static bool cifs_inode_needs_reval(struct inode *inode) |
1da177e4c Linux-2.6.12-rc2 |
1773 |
{ |
df2cf170c cifs: overhaul ci... |
1774 |
struct cifsInodeInfo *cifs_i = CIFS_I(inode); |
6d20e8406 cifs: add attribu... |
1775 |
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
1da177e4c Linux-2.6.12-rc2 |
1776 |
|
18cceb6a7 CIFS: Replace cli... |
1777 |
if (CIFS_CACHE_READ(cifs_i)) |
df2cf170c cifs: overhaul ci... |
1778 |
return false; |
1da177e4c Linux-2.6.12-rc2 |
1779 |
|
df2cf170c cifs: overhaul ci... |
1780 1781 |
if (!lookupCacheEnabled) return true; |
1da177e4c Linux-2.6.12-rc2 |
1782 |
|
df2cf170c cifs: overhaul ci... |
1783 1784 |
if (cifs_i->time == 0) return true; |
1da177e4c Linux-2.6.12-rc2 |
1785 |
|
a87c9ad95 cifs: fix actimeo... |
1786 1787 |
if (!cifs_sb->actimeo) return true; |
6d20e8406 cifs: add attribu... |
1788 1789 |
if (!time_in_range(jiffies, cifs_i->time, cifs_i->time + cifs_sb->actimeo)) |
df2cf170c cifs: overhaul ci... |
1790 |
return true; |
db19272ed cifs: always reva... |
1791 |
/* hardlinked files w/ noserverino get "special" treatment */ |
6d20e8406 cifs: add attribu... |
1792 |
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) && |
db19272ed cifs: always reva... |
1793 1794 |
S_ISREG(inode->i_mode) && inode->i_nlink != 1) return true; |
df2cf170c cifs: overhaul ci... |
1795 1796 |
return false; } |
523fb8c86 cifs: trivial com... |
1797 1798 1799 |
/* * Zap the cache. Called when invalid_mapping flag is set. */ |
6feb9891d CIFS: Simplify in... |
1800 |
int |
df2cf170c cifs: overhaul ci... |
1801 1802 |
cifs_invalidate_mapping(struct inode *inode) { |
6feb9891d CIFS: Simplify in... |
1803 |
int rc = 0; |
df2cf170c cifs: overhaul ci... |
1804 |
|
df2cf170c cifs: overhaul ci... |
1805 |
if (inode->i_mapping && inode->i_mapping->nrpages != 0) { |
257fb1f15 CIFS: Use invalid... |
1806 |
rc = invalidate_inode_pages2(inode->i_mapping); |
4f73c7d34 cifs: fix potenti... |
1807 |
if (rc) |
f96637be0 [CIFS] cifs: Rena... |
1808 1809 1810 |
cifs_dbg(VFS, "%s: could not invalidate inode %p ", __func__, inode); |
df2cf170c cifs: overhaul ci... |
1811 |
} |
257fb1f15 CIFS: Use invalid... |
1812 |
|
9451a9a52 cifs: define inod... |
1813 |
cifs_fscache_reset_inode_cookie(inode); |
6feb9891d CIFS: Simplify in... |
1814 |
return rc; |
df2cf170c cifs: overhaul ci... |
1815 |
} |
4f73c7d34 cifs: fix potenti... |
1816 1817 1818 1819 1820 |
/** * cifs_wait_bit_killable - helper for functions that are sleeping on bit locks * @word: long word containing the bit lock */ static int |
dfd01f026 sched/wait: Fix t... |
1821 |
cifs_wait_bit_killable(struct wait_bit_key *key, int mode) |
4f73c7d34 cifs: fix potenti... |
1822 |
{ |
4f73c7d34 cifs: fix potenti... |
1823 |
freezable_schedule_unsafe(); |
dfd01f026 sched/wait: Fix t... |
1824 1825 |
if (signal_pending_state(mode, current)) return -ERESTARTSYS; |
4f73c7d34 cifs: fix potenti... |
1826 1827 |
return 0; } |
e284e53fd cifs: new helper ... |
1828 1829 1830 |
int cifs_revalidate_mapping(struct inode *inode) { |
4f73c7d34 cifs: fix potenti... |
1831 1832 |
int rc; unsigned long *flags = &CIFS_I(inode)->flags; |
743162013 sched: Remove pro... |
1833 1834 |
rc = wait_on_bit_lock_action(flags, CIFS_INO_LOCK, cifs_wait_bit_killable, TASK_KILLABLE); |
4f73c7d34 cifs: fix potenti... |
1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 |
if (rc) return rc; if (test_and_clear_bit(CIFS_INO_INVALID_MAPPING, flags)) { rc = cifs_invalidate_mapping(inode); if (rc) set_bit(CIFS_INO_INVALID_MAPPING, flags); } clear_bit_unlock(CIFS_INO_LOCK, flags); |
b1cce8032 Merge branch 'for... |
1845 |
smp_mb__after_atomic(); |
4f73c7d34 cifs: fix potenti... |
1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 |
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 ... |
1856 |
} |
6feb9891d CIFS: Simplify in... |
1857 |
int cifs_revalidate_file_attr(struct file *filp) |
abab095d1 cifs: add cifs_re... |
1858 1859 |
{ int rc = 0; |
496ad9aa8 new helper: file_... |
1860 |
struct inode *inode = file_inode(filp); |
ba00ba64c cifs: make variou... |
1861 |
struct cifsFileInfo *cfile = (struct cifsFileInfo *) filp->private_data; |
abab095d1 cifs: add cifs_re... |
1862 1863 |
if (!cifs_inode_needs_reval(inode)) |
6feb9891d CIFS: Simplify in... |
1864 |
return rc; |
abab095d1 cifs: add cifs_re... |
1865 |
|
13cfb7334 cifs: have cifsFi... |
1866 |
if (tlink_tcon(cfile->tlink)->unix_ext) |
abab095d1 cifs: add cifs_re... |
1867 1868 1869 |
rc = cifs_get_file_info_unix(filp); else rc = cifs_get_file_info(filp); |
abab095d1 cifs: add cifs_re... |
1870 1871 |
return rc; } |
6feb9891d CIFS: Simplify in... |
1872 |
int cifs_revalidate_dentry_attr(struct dentry *dentry) |
df2cf170c cifs: overhaul ci... |
1873 |
{ |
6d5786a34 CIFS: Rename Get/... |
1874 |
unsigned int xid; |
df2cf170c cifs: overhaul ci... |
1875 |
int rc = 0; |
2b0143b5c VFS: normal files... |
1876 |
struct inode *inode = d_inode(dentry); |
df2cf170c cifs: overhaul ci... |
1877 |
struct super_block *sb = dentry->d_sb; |
6feb9891d CIFS: Simplify in... |
1878 |
char *full_path = NULL; |
df2cf170c cifs: overhaul ci... |
1879 1880 1881 |
if (inode == NULL) return -ENOENT; |
1da177e4c Linux-2.6.12-rc2 |
1882 |
|
df2cf170c cifs: overhaul ci... |
1883 |
if (!cifs_inode_needs_reval(inode)) |
6feb9891d CIFS: Simplify in... |
1884 |
return rc; |
6d5786a34 CIFS: Rename Get/... |
1885 |
xid = get_xid(); |
1da177e4c Linux-2.6.12-rc2 |
1886 1887 1888 |
/* can not safely grab the rename sem here if rename calls revalidate since that would deadlock */ |
df2cf170c cifs: overhaul ci... |
1889 |
full_path = build_path_from_dentry(dentry); |
1da177e4c Linux-2.6.12-rc2 |
1890 |
if (full_path == NULL) { |
0f3bc09ee cifs: Fix incorre... |
1891 |
rc = -ENOMEM; |
6feb9891d CIFS: Simplify in... |
1892 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
1893 |
} |
f96637be0 [CIFS] cifs: Rena... |
1894 1895 1896 |
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 -... |
1897 |
dentry, cifs_get_time(dentry), jiffies); |
1da177e4c Linux-2.6.12-rc2 |
1898 |
|
0d424ad0a cifs: add cifs_sb... |
1899 |
if (cifs_sb_master_tcon(CIFS_SB(sb))->unix_ext) |
df2cf170c cifs: overhaul ci... |
1900 1901 1902 1903 |
rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid); else rc = cifs_get_inode_info(&inode, full_path, NULL, sb, xid, NULL); |
1da177e4c Linux-2.6.12-rc2 |
1904 |
|
6feb9891d CIFS: Simplify in... |
1905 |
out: |
1da177e4c Linux-2.6.12-rc2 |
1906 |
kfree(full_path); |
6d5786a34 CIFS: Rename Get/... |
1907 |
free_xid(xid); |
1da177e4c Linux-2.6.12-rc2 |
1908 1909 |
return rc; } |
6feb9891d CIFS: Simplify in... |
1910 1911 1912 |
int cifs_revalidate_file(struct file *filp) { int rc; |
496ad9aa8 new helper: file_... |
1913 |
struct inode *inode = file_inode(filp); |
6feb9891d CIFS: Simplify in... |
1914 1915 1916 1917 |
rc = cifs_revalidate_file_attr(filp); if (rc) return rc; |
e284e53fd cifs: new helper ... |
1918 |
return cifs_revalidate_mapping(inode); |
6feb9891d CIFS: Simplify in... |
1919 1920 1921 1922 1923 1924 |
} /* revalidate a dentry's inode attributes */ int cifs_revalidate_dentry(struct dentry *dentry) { int rc; |
2b0143b5c VFS: normal files... |
1925 |
struct inode *inode = d_inode(dentry); |
6feb9891d CIFS: Simplify in... |
1926 1927 1928 1929 |
rc = cifs_revalidate_dentry_attr(dentry); if (rc) return rc; |
e284e53fd cifs: new helper ... |
1930 |
return cifs_revalidate_mapping(inode); |
6feb9891d CIFS: Simplify in... |
1931 |
} |
1da177e4c Linux-2.6.12-rc2 |
1932 |
int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry, |
1c456013e cifs: on multiuse... |
1933 |
struct kstat *stat) |
1da177e4c Linux-2.6.12-rc2 |
1934 |
{ |
3aa1c8c29 cifs: on multiuse... |
1935 |
struct cifs_sb_info *cifs_sb = CIFS_SB(dentry->d_sb); |
96daf2b09 [CIFS] Rename thr... |
1936 |
struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); |
2b0143b5c VFS: normal files... |
1937 |
struct inode *inode = d_inode(dentry); |
6feb9891d CIFS: Simplify in... |
1938 |
int rc; |
3aa1c8c29 cifs: on multiuse... |
1939 |
|
6feb9891d CIFS: Simplify in... |
1940 1941 1942 1943 |
/* * We need to be sure that all dirty pages are written and the server * has actual ctime, mtime and file length. */ |
18cceb6a7 CIFS: Replace cli... |
1944 |
if (!CIFS_CACHE_READ(CIFS_I(inode)) && inode->i_mapping && |
6feb9891d CIFS: Simplify in... |
1945 1946 |
inode->i_mapping->nrpages != 0) { rc = filemap_fdatawait(inode->i_mapping); |
156ecb2d8 [CIFS] Fix to pro... |
1947 1948 1949 1950 |
if (rc) { mapping_set_error(inode->i_mapping, rc); return rc; } |
6feb9891d CIFS: Simplify in... |
1951 |
} |
1c456013e cifs: on multiuse... |
1952 |
|
6feb9891d CIFS: Simplify in... |
1953 1954 1955 1956 1957 1958 1959 1960 1961 |
rc = cifs_revalidate_dentry_attr(dentry); if (rc) return rc; generic_fillattr(inode, stat); stat->blksize = CIFS_MAX_MSGSIZE; stat->ino = CIFS_I(inode)->uniqueid; /* |
d3d1fce11 cifs: don't overr... |
1962 1963 1964 |
* 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... |
1965 1966 |
*/ if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER) && |
d3d1fce11 cifs: don't overr... |
1967 |
!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) && |
6feb9891d CIFS: Simplify in... |
1968 1969 1970 1971 1972 |
!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... |
1973 |
} |
6feb9891d CIFS: Simplify in... |
1974 |
return rc; |
1da177e4c Linux-2.6.12-rc2 |
1975 1976 1977 1978 |
} static int cifs_truncate_page(struct address_space *mapping, loff_t from) { |
09cbfeaf1 mm, fs: get rid o... |
1979 1980 |
pgoff_t index = from >> PAGE_SHIFT; unsigned offset = from & (PAGE_SIZE - 1); |
1da177e4c Linux-2.6.12-rc2 |
1981 |
struct page *page; |
1da177e4c Linux-2.6.12-rc2 |
1982 1983 1984 1985 1986 |
int rc = 0; page = grab_cache_page(mapping, index); if (!page) return -ENOMEM; |
09cbfeaf1 mm, fs: get rid o... |
1987 |
zero_user_segment(page, offset, PAGE_SIZE); |
1da177e4c Linux-2.6.12-rc2 |
1988 |
unlock_page(page); |
09cbfeaf1 mm, fs: get rid o... |
1989 |
put_page(page); |
1da177e4c Linux-2.6.12-rc2 |
1990 1991 |
return rc; } |
1b9474635 cifs: truncate fa... |
1992 |
static void cifs_setsize(struct inode *inode, loff_t offset) |
3677db10a [CIFS] Fix lockin... |
1993 |
{ |
ba6a46a03 [CIFS] small piec... |
1994 |
spin_lock(&inode->i_lock); |
3677db10a [CIFS] Fix lockin... |
1995 |
i_size_write(inode, offset); |
ba6a46a03 [CIFS] small piec... |
1996 |
spin_unlock(&inode->i_lock); |
1b9474635 cifs: truncate fa... |
1997 |
|
7caef2676 truncate: drop 'o... |
1998 |
truncate_pagecache(inode, offset); |
3677db10a [CIFS] Fix lockin... |
1999 |
} |
8efdbde64 [CIFS] break ATTR... |
2000 2001 |
static int cifs_set_file_size(struct inode *inode, struct iattr *attrs, |
6d5786a34 CIFS: Rename Get/... |
2002 |
unsigned int xid, char *full_path) |
8efdbde64 [CIFS] break ATTR... |
2003 2004 2005 2006 2007 |
{ 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... |
2008 |
struct tcon_link *tlink = NULL; |
d14334181 CIFS: Move set_fi... |
2009 2010 |
struct cifs_tcon *tcon = NULL; struct TCP_Server_Info *server; |
8efdbde64 [CIFS] break ATTR... |
2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 |
/* * 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 */ |
6508d904e cifs: have find_r... |
2021 |
open_file = find_writable_file(cifsInode, true); |
8efdbde64 [CIFS] break ATTR... |
2022 |
if (open_file) { |
d14334181 CIFS: Move set_fi... |
2023 2024 2025 2026 2027 2028 2029 |
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... |
2030 |
cifsFileInfo_put(open_file); |
f96637be0 [CIFS] cifs: Rena... |
2031 2032 |
cifs_dbg(FYI, "SetFSize for attrs rc = %d ", rc); |
8efdbde64 [CIFS] break ATTR... |
2033 2034 |
} else rc = -EINVAL; |
d14334181 CIFS: Move set_fi... |
2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 |
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... |
2045 |
|
d14334181 CIFS: Move set_fi... |
2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 |
/* * 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... |
2056 2057 |
cifs_dbg(FYI, "SetEOF by path (setattrs) rc = %d ", rc); |
d14334181 CIFS: Move set_fi... |
2058 |
|
d14334181 CIFS: Move set_fi... |
2059 2060 |
if (tlink) cifs_put_tlink(tlink); |
8efdbde64 [CIFS] break ATTR... |
2061 |
|
d14334181 CIFS: Move set_fi... |
2062 |
set_size_out: |
8efdbde64 [CIFS] break ATTR... |
2063 |
if (rc == 0) { |
fbec9ab95 cifs: vary timeou... |
2064 |
cifsInode->server_eof = attrs->ia_size; |
1b9474635 cifs: truncate fa... |
2065 |
cifs_setsize(inode, attrs->ia_size); |
8efdbde64 [CIFS] break ATTR... |
2066 2067 2068 2069 2070 |
cifs_truncate_page(inode->i_mapping, inode->i_size); } return rc; } |
3fe5c1dd0 spin off cifs_set... |
2071 2072 2073 2074 |
static int cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs) { int rc; |
6d5786a34 CIFS: Rename Get/... |
2075 |
unsigned int xid; |
3fe5c1dd0 spin off cifs_set... |
2076 |
char *full_path = NULL; |
2b0143b5c VFS: normal files... |
2077 |
struct inode *inode = d_inode(direntry); |
3fe5c1dd0 spin off cifs_set... |
2078 2079 |
struct cifsInodeInfo *cifsInode = CIFS_I(inode); struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
7ffec3724 cifs: add refcoun... |
2080 |
struct tcon_link *tlink; |
96daf2b09 [CIFS] Rename thr... |
2081 |
struct cifs_tcon *pTcon; |
3fe5c1dd0 spin off cifs_set... |
2082 |
struct cifs_unix_set_info_args *args = NULL; |
3bbeeb3c9 cifs: add and use... |
2083 |
struct cifsFileInfo *open_file; |
3fe5c1dd0 spin off cifs_set... |
2084 |
|
35c265e00 cifs: switch to u... |
2085 2086 2087 |
cifs_dbg(FYI, "setattr_unix on file %pd attrs->ia_valid=0x%x ", direntry, attrs->ia_valid); |
3fe5c1dd0 spin off cifs_set... |
2088 |
|
6d5786a34 CIFS: Rename Get/... |
2089 |
xid = get_xid(); |
3fe5c1dd0 spin off cifs_set... |
2090 |
|
db78b877f always call inode... |
2091 2092 |
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) attrs->ia_valid |= ATTR_FORCE; |
31051c85b fs: Give dentry t... |
2093 |
rc = setattr_prepare(direntry, attrs); |
db78b877f always call inode... |
2094 2095 |
if (rc < 0) goto out; |
3fe5c1dd0 spin off cifs_set... |
2096 2097 2098 2099 2100 2101 |
full_path = build_path_from_dentry(direntry); if (full_path == NULL) { rc = -ENOMEM; goto out; } |
0f4d634c5 cifs: flush data ... |
2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 |
/* * 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); |
eb4b756b1 cifs: eliminate c... |
2114 2115 |
mapping_set_error(inode->i_mapping, rc); rc = 0; |
3fe5c1dd0 spin off cifs_set... |
2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 |
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... |
2142 |
args->uid = INVALID_UID; /* no change */ |
3fe5c1dd0 spin off cifs_set... |
2143 2144 2145 2146 |
if (attrs->ia_valid & ATTR_GID) args->gid = attrs->ia_gid; else |
49418b2c2 cifs: Modify stru... |
2147 |
args->gid = INVALID_GID; /* no change */ |
3fe5c1dd0 spin off cifs_set... |
2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 |
if (attrs->ia_valid & ATTR_ATIME) args->atime = cifs_UnixTimeToNT(attrs->ia_atime); else args->atime = NO_CHANGE_64; if (attrs->ia_valid & ATTR_MTIME) args->mtime = cifs_UnixTimeToNT(attrs->ia_mtime); else args->mtime = NO_CHANGE_64; if (attrs->ia_valid & ATTR_CTIME) args->ctime = cifs_UnixTimeToNT(attrs->ia_ctime); else args->ctime = NO_CHANGE_64; args->device = 0; |
6508d904e cifs: have find_r... |
2165 |
open_file = find_writable_file(cifsInode, true); |
3bbeeb3c9 cifs: add and use... |
2166 |
if (open_file) { |
4b4de76e3 CIFS: Replace net... |
2167 |
u16 nfid = open_file->fid.netfid; |
3bbeeb3c9 cifs: add and use... |
2168 |
u32 npid = open_file->pid; |
13cfb7334 cifs: have cifsFi... |
2169 |
pTcon = tlink_tcon(open_file->tlink); |
3bbeeb3c9 cifs: add and use... |
2170 |
rc = CIFSSMBUnixSetFileInfo(xid, pTcon, args, nfid, npid); |
6ab409b53 cifs: Replace wrt... |
2171 |
cifsFileInfo_put(open_file); |
3bbeeb3c9 cifs: add and use... |
2172 |
} else { |
7ffec3724 cifs: add refcoun... |
2173 2174 2175 2176 2177 2178 |
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... |
2179 |
rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, args, |
01ea95e3b cifs: rename CIFS... |
2180 |
cifs_sb->local_nls, |
bc8ebdc4f Fix that several ... |
2181 |
cifs_remap(cifs_sb)); |
7ffec3724 cifs: add refcoun... |
2182 |
cifs_put_tlink(tlink); |
3bbeeb3c9 cifs: add and use... |
2183 |
} |
3fe5c1dd0 spin off cifs_set... |
2184 |
|
1025774ce remove inode_setattr |
2185 2186 |
if (rc) goto out; |
ccd4bb1be [CIFS] Don't cach... |
2187 |
|
1025774ce remove inode_setattr |
2188 |
if ((attrs->ia_valid & ATTR_SIZE) && |
1b9474635 cifs: truncate fa... |
2189 2190 |
attrs->ia_size != i_size_read(inode)) truncate_setsize(inode, attrs->ia_size); |
1025774ce remove inode_setattr |
2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 |
setattr_copy(inode, attrs); 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... |
2203 2204 2205 |
out: kfree(args); kfree(full_path); |
6d5786a34 CIFS: Rename Get/... |
2206 |
free_xid(xid); |
3fe5c1dd0 spin off cifs_set... |
2207 2208 |
return rc; } |
0510eeb73 turn cifs_setattr... |
2209 2210 |
static int cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) |
1da177e4c Linux-2.6.12-rc2 |
2211 |
{ |
6d5786a34 CIFS: Rename Get/... |
2212 |
unsigned int xid; |
8abf2775d cifs: Use kuids a... |
2213 2214 |
kuid_t uid = INVALID_UID; kgid_t gid = INVALID_GID; |
2b0143b5c VFS: normal files... |
2215 |
struct inode *inode = d_inode(direntry); |
3fe5c1dd0 spin off cifs_set... |
2216 |
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
3fe5c1dd0 spin off cifs_set... |
2217 |
struct cifsInodeInfo *cifsInode = CIFS_I(inode); |
1da177e4c Linux-2.6.12-rc2 |
2218 2219 |
char *full_path = NULL; int rc = -EACCES; |
feb3e20ce move file time an... |
2220 |
__u32 dosattr = 0; |
4e1e7fb9e bundle up Unix SE... |
2221 |
__u64 mode = NO_CHANGE_64; |
3fe5c1dd0 spin off cifs_set... |
2222 |
|
6d5786a34 CIFS: Rename Get/... |
2223 |
xid = get_xid(); |
1da177e4c Linux-2.6.12-rc2 |
2224 |
|
35c265e00 cifs: switch to u... |
2225 2226 2227 |
cifs_dbg(FYI, "setattr on file %pd attrs->iavalid 0x%x ", direntry, attrs->ia_valid); |
6473a559c [CIFS] Fix missin... |
2228 |
|
db78b877f always call inode... |
2229 2230 |
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) attrs->ia_valid |= ATTR_FORCE; |
31051c85b fs: Give dentry t... |
2231 |
rc = setattr_prepare(direntry, attrs); |
db78b877f always call inode... |
2232 |
if (rc < 0) { |
6d5786a34 CIFS: Rename Get/... |
2233 |
free_xid(xid); |
db78b877f always call inode... |
2234 |
return rc; |
6473a559c [CIFS] Fix missin... |
2235 |
} |
50c2f7538 [CIFS] whitespace... |
2236 |
|
7f57356b7 [CIFS] Remove cif... |
2237 |
full_path = build_path_from_dentry(direntry); |
1da177e4c Linux-2.6.12-rc2 |
2238 |
if (full_path == NULL) { |
0f3bc09ee cifs: Fix incorre... |
2239 |
rc = -ENOMEM; |
6d5786a34 CIFS: Rename Get/... |
2240 |
free_xid(xid); |
0f3bc09ee cifs: Fix incorre... |
2241 |
return rc; |
1da177e4c Linux-2.6.12-rc2 |
2242 |
} |
1da177e4c Linux-2.6.12-rc2 |
2243 |
|
0f4d634c5 cifs: flush data ... |
2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 |
/* * 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); |
eb4b756b1 cifs: eliminate c... |
2256 2257 |
mapping_set_error(inode->i_mapping, rc); rc = 0; |
cea218054 [CIFS] Fix potent... |
2258 |
|
50531444f [CIFS] Fix mtime ... |
2259 |
if (attrs->ia_valid & ATTR_SIZE) { |
8efdbde64 [CIFS] break ATTR... |
2260 2261 |
rc = cifs_set_file_size(inode, attrs, xid, full_path); if (rc != 0) |
e30dcf3a1 [CIFS] Add suppor... |
2262 |
goto cifs_setattr_exit; |
1da177e4c Linux-2.6.12-rc2 |
2263 |
} |
4ca691a89 silently ignore o... |
2264 |
|
a5ff37696 cifs: Call id to ... |
2265 2266 2267 2268 2269 2270 2271 2272 |
if (attrs->ia_valid & ATTR_UID) uid = attrs->ia_uid; if (attrs->ia_valid & ATTR_GID) gid = attrs->ia_gid; #ifdef CONFIG_CIFS_ACL if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { |
8abf2775d cifs: Use kuids a... |
2273 |
if (uid_valid(uid) || gid_valid(gid)) { |
a5ff37696 cifs: Call id to ... |
2274 2275 2276 |
rc = id_mode_to_cifs_acl(inode, full_path, NO_CHANGE_64, uid, gid); if (rc) { |
f96637be0 [CIFS] cifs: Rena... |
2277 2278 2279 |
cifs_dbg(FYI, "%s: Setting id failed with error: %d ", __func__, rc); |
a5ff37696 cifs: Call id to ... |
2280 2281 2282 2283 2284 |
goto cifs_setattr_exit; } } } else #endif /* CONFIG_CIFS_ACL */ |
3fe5c1dd0 spin off cifs_set... |
2285 |
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)) |
4ca691a89 silently ignore o... |
2286 |
attrs->ia_valid &= ~(ATTR_UID | ATTR_GID); |
1da177e4c Linux-2.6.12-rc2 |
2287 |
|
d32c4f262 CIFS: ignore mode... |
2288 2289 2290 |
/* 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 |
2291 |
if (attrs->ia_valid & ATTR_MODE) { |
1da177e4c Linux-2.6.12-rc2 |
2292 |
mode = attrs->ia_mode; |
cdbce9c87 [CIFS] Fix setatt... |
2293 |
rc = 0; |
79df1baee cifs: fix use of ... |
2294 |
#ifdef CONFIG_CIFS_ACL |
78415d2d3 cifs: Misc. clean... |
2295 |
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { |
a5ff37696 cifs: Call id to ... |
2296 |
rc = id_mode_to_cifs_acl(inode, full_path, mode, |
8abf2775d cifs: Use kuids a... |
2297 |
INVALID_UID, INVALID_GID); |
78415d2d3 cifs: Misc. clean... |
2298 |
if (rc) { |
f96637be0 [CIFS] cifs: Rena... |
2299 2300 2301 |
cifs_dbg(FYI, "%s: Setting ACL failed with error: %d ", __func__, rc); |
78415d2d3 cifs: Misc. clean... |
2302 2303 2304 |
goto cifs_setattr_exit; } } else |
79df1baee cifs: fix use of ... |
2305 |
#endif /* CONFIG_CIFS_ACL */ |
5132861a7 disable most mode... |
2306 2307 |
if (((mode & S_IWUGO) == 0) && (cifsInode->cifsAttrs & ATTR_READONLY) == 0) { |
feb3e20ce move file time an... |
2308 2309 |
dosattr = cifsInode->cifsAttrs | ATTR_READONLY; |
5132861a7 disable most mode... |
2310 2311 2312 2313 2314 |
/* 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... |
2315 2316 2317 2318 2319 |
dosattr = cifsInode->cifsAttrs & ~ATTR_READONLY; /* Attributes of 0 are ignored */ if (dosattr == 0) dosattr |= ATTR_NORMAL; |
5132861a7 disable most mode... |
2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 |
/* 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 |= cifs_sb->mnt_dir_mode; else attrs->ia_mode |= cifs_sb->mnt_file_mode; } } 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 |
2334 |
} |
1da177e4c Linux-2.6.12-rc2 |
2335 |
} |
feb3e20ce move file time an... |
2336 2337 2338 2339 |
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 |
2340 |
|
e30dcf3a1 [CIFS] Add suppor... |
2341 2342 2343 2344 2345 |
/* 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... |
2346 |
if ((rc) && (attrs->ia_valid & |
feb3e20ce move file time an... |
2347 |
(ATTR_MODE | ATTR_GID | ATTR_UID | ATTR_SIZE))) |
e30dcf3a1 [CIFS] Add suppor... |
2348 |
rc = 0; |
1da177e4c Linux-2.6.12-rc2 |
2349 2350 2351 2352 |
} /* do not need local check to inode_check_ok since the server does that */ |
1025774ce remove inode_setattr |
2353 2354 2355 2356 |
if (rc) goto cifs_setattr_exit; if ((attrs->ia_valid & ATTR_SIZE) && |
1b9474635 cifs: truncate fa... |
2357 2358 |
attrs->ia_size != i_size_read(inode)) truncate_setsize(inode, attrs->ia_size); |
1025774ce remove inode_setattr |
2359 2360 2361 |
setattr_copy(inode, attrs); mark_inode_dirty(inode); |
1025774ce remove inode_setattr |
2362 |
|
e30dcf3a1 [CIFS] Add suppor... |
2363 |
cifs_setattr_exit: |
1da177e4c Linux-2.6.12-rc2 |
2364 |
kfree(full_path); |
6d5786a34 CIFS: Rename Get/... |
2365 |
free_xid(xid); |
1da177e4c Linux-2.6.12-rc2 |
2366 2367 |
return rc; } |
0510eeb73 turn cifs_setattr... |
2368 2369 2370 |
int cifs_setattr(struct dentry *direntry, struct iattr *attrs) { |
fc64005c9 don't bother with... |
2371 |
struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb); |
96daf2b09 [CIFS] Rename thr... |
2372 |
struct cifs_tcon *pTcon = cifs_sb_master_tcon(cifs_sb); |
0510eeb73 turn cifs_setattr... |
2373 2374 2375 2376 2377 2378 2379 2380 |
if (pTcon->unix_ext) return cifs_setattr_unix(direntry, attrs); return cifs_setattr_nounix(direntry, attrs); /* BB: add cifs_setattr_legacy for really old servers */ } |
99ee4dbd7 [CIFS] Remove som... |
2381 |
#if 0 |
1da177e4c Linux-2.6.12-rc2 |
2382 2383 |
void cifs_delete_inode(struct inode *inode) { |
f96637be0 [CIFS] cifs: Rena... |
2384 2385 |
cifs_dbg(FYI, "In cifs_delete_inode, inode = 0x%p ", inode); |
1da177e4c Linux-2.6.12-rc2 |
2386 2387 2388 |
/* may have to add back in if and when safe distributed caching of directories added e.g. via FindNotify */ } |
99ee4dbd7 [CIFS] Remove som... |
2389 |
#endif |