summaryrefslogtreecommitdiff
path: root/fs/cifs/inode.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-05-18 07:18:38 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2010-05-18 07:18:38 -0700
commitfd25a1f556760dbd6e29dec66c70223a8912cdb2 (patch)
tree73ff80b35cb90949612ccc4f548fc6dcdae0897c /fs/cifs/inode.c
parentba2e1c5f25a99dec3873745031ad23ce3fd79bff (diff)
parent4065c802da7484fa36f8cdf10f18d087233ecb88 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6: (23 commits) cifs: fix noserverino handling when unix extensions are enabled cifs: don't update uniqueid in cifs_fattr_to_inode cifs: always revalidate hardlinked inodes when using noserverino [CIFS] drop quota operation stubs cifs: propagate cifs_new_fileinfo() error back to the caller cifs: add comments explaining cifs_new_fileinfo behavior cifs: remove unused parameter from cifs_posix_open_inode_helper() [CIFS] Remove unused cifs_oplock_cachep cifs: have decode_negTokenInit set flags in server struct cifs: break negotiate protocol calls out of cifs_setup_session cifs: eliminate "first_time" parm to CIFS_SessSetup [CIFS] Fix lease break for writes cifs: save the dialect chosen by server cifs: change && to || cifs: rename "extended_security" to "global_secflags" cifs: move tcon find/create into separate function cifs: move SMB session creation code into separate function cifs: track local_nls in volume info [CIFS] Allow null nd (as nfs server uses) on create [CIFS] Fix losing locks during fork() ...
Diffstat (limited to 'fs/cifs/inode.c')
-rw-r--r--fs/cifs/inode.c123
1 files changed, 70 insertions, 53 deletions
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 29b9ea244c81..62b324f26a56 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -1,7 +1,7 @@
/*
* fs/cifs/inode.c
*
- * Copyright (C) International Business Machines Corp., 2002,2008
+ * Copyright (C) International Business Machines Corp., 2002,2010
* Author(s): Steve French (sfrench@us.ibm.com)
*
* This library is free software; you can redistribute it and/or modify
@@ -86,30 +86,30 @@ cifs_revalidate_cache(struct inode *inode, struct cifs_fattr *fattr)
{
struct cifsInodeInfo *cifs_i = CIFS_I(inode);
- cFYI(1, ("%s: revalidating inode %llu", __func__, cifs_i->uniqueid));
+ cFYI(1, "%s: revalidating inode %llu", __func__, cifs_i->uniqueid);
if (inode->i_state & I_NEW) {
- cFYI(1, ("%s: inode %llu is new", __func__, cifs_i->uniqueid));
+ cFYI(1, "%s: inode %llu is new", __func__, cifs_i->uniqueid);
return;
}
/* don't bother with revalidation if we have an oplock */
if (cifs_i->clientCanCacheRead) {
- cFYI(1, ("%s: inode %llu is oplocked", __func__,
- cifs_i->uniqueid));
+ cFYI(1, "%s: inode %llu is oplocked", __func__,
+ cifs_i->uniqueid);
return;
}
/* revalidate if mtime or size have changed */
if (timespec_equal(&inode->i_mtime, &fattr->cf_mtime) &&
cifs_i->server_eof == fattr->cf_eof) {
- cFYI(1, ("%s: inode %llu is unchanged", __func__,
- cifs_i->uniqueid));
+ cFYI(1, "%s: inode %llu is unchanged", __func__,
+ cifs_i->uniqueid);
return;
}
- cFYI(1, ("%s: invalidating inode %llu mapping", __func__,
- cifs_i->uniqueid));
+ cFYI(1, "%s: invalidating inode %llu mapping", __func__,
+ cifs_i->uniqueid);
cifs_i->invalid_mapping = true;
}
@@ -137,15 +137,14 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
inode->i_mode = fattr->cf_mode;
cifs_i->cifsAttrs = fattr->cf_cifsattrs;
- cifs_i->uniqueid = fattr->cf_uniqueid;
if (fattr->cf_flags & CIFS_FATTR_NEED_REVAL)
cifs_i->time = 0;
else
cifs_i->time = jiffies;
- cFYI(1, ("inode 0x%p old_time=%ld new_time=%ld", inode,
- oldtime, cifs_i->time));
+ cFYI(1, "inode 0x%p old_time=%ld new_time=%ld", inode,
+ oldtime, cifs_i->time);
cifs_i->delete_pending = fattr->cf_flags & CIFS_FATTR_DELETE_PENDING;
@@ -170,6 +169,17 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
cifs_set_ops(inode, fattr->cf_flags & CIFS_FATTR_DFS_REFERRAL);
}
+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);
+}
+
/* 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,
@@ -227,7 +237,7 @@ cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, FILE_UNIX_BASIC_INFO *info,
/* safest to call it a file if we do not know */
fattr->cf_mode |= S_IFREG;
fattr->cf_dtype = DT_REG;
- cFYI(1, ("unknown type %d", le32_to_cpu(info->Type)));
+ cFYI(1, "unknown type %d", le32_to_cpu(info->Type));
break;
}
@@ -256,7 +266,7 @@ cifs_create_dfs_fattr(struct cifs_fattr *fattr, struct super_block *sb)
{
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
- cFYI(1, ("creating fake fattr for DFS referral"));
+ cFYI(1, "creating fake fattr for DFS referral");
memset(fattr, 0, sizeof(*fattr));
fattr->cf_mode = S_IFDIR | S_IXUGO | S_IRWXU;
@@ -305,7 +315,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
tcon = cifs_sb->tcon;
- cFYI(1, ("Getting info on %s", full_path));
+ cFYI(1, "Getting info on %s", full_path);
/* could have done a find first instead but this returns more info */
rc = CIFSSMBUnixQPathInfo(xid, tcon, full_path, &find_data,
@@ -323,6 +333,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
if (*pinode == NULL) {
/* get new inode */
+ cifs_fill_uniqueid(sb, &fattr);
*pinode = cifs_iget(sb, &fattr);
if (!*pinode)
rc = -ENOMEM;
@@ -373,7 +384,7 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
&bytes_read, &pbuf, &buf_type);
if ((rc == 0) && (bytes_read >= 8)) {
if (memcmp("IntxBLK", pbuf, 8) == 0) {
- cFYI(1, ("Block device"));
+ cFYI(1, "Block device");
fattr->cf_mode |= S_IFBLK;
fattr->cf_dtype = DT_BLK;
if (bytes_read == 24) {
@@ -385,7 +396,7 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
fattr->cf_rdev = MKDEV(mjr, mnr);
}
} else if (memcmp("IntxCHR", pbuf, 8) == 0) {
- cFYI(1, ("Char device"));
+ cFYI(1, "Char device");
fattr->cf_mode |= S_IFCHR;
fattr->cf_dtype = DT_CHR;
if (bytes_read == 24) {
@@ -397,7 +408,7 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
fattr->cf_rdev = MKDEV(mjr, mnr);
}
} else if (memcmp("IntxLNK", pbuf, 7) == 0) {
- cFYI(1, ("Symlink"));
+ cFYI(1, "Symlink");
fattr->cf_mode |= S_IFLNK;
fattr->cf_dtype = DT_LNK;
} else {
@@ -439,10 +450,10 @@ static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path,
else if (rc > 3) {
mode = le32_to_cpu(*((__le32 *)ea_value));
fattr->cf_mode &= ~SFBITS_MASK;
- cFYI(1, ("special bits 0%o org mode 0%o", mode,
- fattr->cf_mode));
+ cFYI(1, "special bits 0%o org mode 0%o", mode,
+ fattr->cf_mode);
fattr->cf_mode = (mode & SFBITS_MASK) | fattr->cf_mode;
- cFYI(1, ("special mode bits 0%o", mode));
+ cFYI(1, "special mode bits 0%o", mode);
}
return 0;
@@ -548,11 +559,11 @@ int cifs_get_inode_info(struct inode **pinode,
struct cifs_fattr fattr;
pTcon = cifs_sb->tcon;
- cFYI(1, ("Getting info on %s", full_path));
+ cFYI(1, "Getting info on %s", full_path);
if ((pfindData == NULL) && (*pinode != NULL)) {
if (CIFS_I(*pinode)->clientCanCacheRead) {
- cFYI(1, ("No need to revalidate cached inode sizes"));
+ cFYI(1, "No need to revalidate cached inode sizes");
return rc;
}
}
@@ -618,7 +629,7 @@ int cifs_get_inode_info(struct inode **pinode,
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
if (rc1 || !fattr.cf_uniqueid) {
- cFYI(1, ("GetSrvInodeNum rc %d", rc1));
+ cFYI(1, "GetSrvInodeNum rc %d", rc1);
fattr.cf_uniqueid = iunique(sb, ROOT_I);
cifs_autodisable_serverino(cifs_sb);
}
@@ -634,13 +645,13 @@ int cifs_get_inode_info(struct inode **pinode,
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
tmprc = cifs_sfu_type(&fattr, full_path, cifs_sb, xid);
if (tmprc)
- cFYI(1, ("cifs_sfu_type failed: %d", tmprc));
+ cFYI(1, "cifs_sfu_type failed: %d", tmprc);
}
#ifdef CONFIG_CIFS_EXPERIMENTAL
/* fill in 0777 bits from ACL */
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
- cFYI(1, ("Getting mode bits from ACL"));
+ cFYI(1, "Getting mode bits from ACL");
cifs_acl_to_fattr(cifs_sb, &fattr, *pinode, full_path, pfid);
}
#endif
@@ -745,7 +756,7 @@ cifs_iget(struct super_block *sb, struct cifs_fattr *fattr)
struct inode *inode;
retry_iget5_locked:
- cFYI(1, ("looking for uniqueid=%llu", fattr->cf_uniqueid));
+ cFYI(1, "looking for uniqueid=%llu", fattr->cf_uniqueid);
/* hash down to 32-bits on 32-bit arch */
hash = cifs_uniqueid_to_ino_t(fattr->cf_uniqueid);
@@ -797,7 +808,7 @@ struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino)
return ERR_PTR(-ENOMEM);
if (rc && cifs_sb->tcon->ipc) {
- cFYI(1, ("ipc connection - fake read inode"));
+ cFYI(1, "ipc connection - fake read inode");
inode->i_mode |= S_IFDIR;
inode->i_nlink = 2;
inode->i_op = &cifs_ipc_inode_ops;
@@ -859,7 +870,7 @@ cifs_set_file_info(struct inode *inode, struct iattr *attrs, int xid,
* server times.
*/
if (set_time && (attrs->ia_valid & ATTR_CTIME)) {
- cFYI(1, ("CIFS - CTIME changed"));
+ cFYI(1, "CIFS - CTIME changed");
info_buf.ChangeTime =
cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_ctime));
} else
@@ -894,8 +905,8 @@ cifs_set_file_info(struct inode *inode, struct iattr *attrs, int xid,
goto out;
}
- cFYI(1, ("calling SetFileInfo since SetPathInfo for "
- "times not supported by this server"));
+ cFYI(1, "calling SetFileInfo since SetPathInfo for "
+ "times not supported by this server");
rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN,
SYNCHRONIZE | FILE_WRITE_ATTRIBUTES,
CREATE_NOT_DIR, &netfid, &oplock,
@@ -1053,7 +1064,7 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry)
struct iattr *attrs = NULL;
__u32 dosattr = 0, origattr = 0;
- cFYI(1, ("cifs_unlink, dir=0x%p, dentry=0x%p", dir, dentry));
+ cFYI(1, "cifs_unlink, dir=0x%p, dentry=0x%p", dir, dentry);
xid = GetXid();
@@ -1072,7 +1083,7 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry)
rc = CIFSPOSIXDelFile(xid, tcon, full_path,
SMB_POSIX_UNLINK_FILE_TARGET, cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
- cFYI(1, ("posix del rc %d", rc));
+ cFYI(1, "posix del rc %d", rc);
if ((rc == 0) || (rc == -ENOENT))
goto psx_del_no_retry;
}
@@ -1146,7 +1157,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
struct inode *newinode = NULL;
struct cifs_fattr fattr;
- cFYI(1, ("In cifs_mkdir, mode = 0x%x inode = 0x%p", mode, inode));
+ cFYI(1, "In cifs_mkdir, mode = 0x%x inode = 0x%p", mode, inode);
xid = GetXid();
@@ -1181,7 +1192,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
kfree(pInfo);
goto mkdir_retry_old;
} else if (rc) {
- cFYI(1, ("posix mkdir returned 0x%x", rc));
+ cFYI(1, "posix mkdir returned 0x%x", rc);
d_drop(direntry);
} else {
if (pInfo->Type == cpu_to_le32(-1)) {
@@ -1198,6 +1209,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
direntry->d_op = &cifs_dentry_ops;
cifs_unix_basic_to_fattr(&fattr, pInfo, cifs_sb);
+ cifs_fill_uniqueid(inode->i_sb, &fattr);
newinode = cifs_iget(inode->i_sb, &fattr);
if (!newinode) {
kfree(pInfo);
@@ -1207,12 +1219,12 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
d_instantiate(direntry, newinode);
#ifdef CONFIG_CIFS_DEBUG2
- cFYI(1, ("instantiated dentry %p %s to inode %p",
- direntry, direntry->d_name.name, newinode));
+ cFYI(1, "instantiated dentry %p %s to inode %p",
+ direntry, direntry->d_name.name, newinode);
if (newinode->i_nlink != 2)
- cFYI(1, ("unexpected number of links %d",
- newinode->i_nlink));
+ cFYI(1, "unexpected number of links %d",
+ newinode->i_nlink);
#endif
}
kfree(pInfo);
@@ -1223,7 +1235,7 @@ mkdir_retry_old:
rc = CIFSSMBMkDir(xid, pTcon, full_path, cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
if (rc) {
- cFYI(1, ("cifs_mkdir returned 0x%x", rc));
+ cFYI(1, "cifs_mkdir returned 0x%x", rc);
d_drop(direntry);
} else {
mkdir_get_info:
@@ -1326,7 +1338,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
char *full_path = NULL;
struct cifsInodeInfo *cifsInode;
- cFYI(1, ("cifs_rmdir, inode = 0x%p", inode));
+ cFYI(1, "cifs_rmdir, inode = 0x%p", inode);
xid = GetXid();
@@ -1528,6 +1540,11 @@ cifs_inode_needs_reval(struct inode *inode)
if (time_after_eq(jiffies, cifs_i->time + HZ))
return true;
+ /* hardlinked files w/ noserverino get "special" treatment */
+ if (!(CIFS_SB(inode->i_sb)->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) &&
+ S_ISREG(inode->i_mode) && inode->i_nlink != 1)
+ return true;
+
return false;
}
@@ -1594,9 +1611,9 @@ int cifs_revalidate_dentry(struct dentry *dentry)
goto check_inval;
}
- cFYI(1, ("Revalidate: %s inode 0x%p count %d dentry: 0x%p d_time %ld "
+ cFYI(1, "Revalidate: %s inode 0x%p count %d dentry: 0x%p d_time %ld "
"jiffies %ld", full_path, inode, inode->i_count.counter,
- dentry, dentry->d_time, jiffies));
+ dentry, dentry->d_time, jiffies);
if (CIFS_SB(sb)->tcon->unix_ext)
rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
@@ -1690,12 +1707,12 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, nfid,
npid, false);
cifsFileInfo_put(open_file);
- cFYI(1, ("SetFSize for attrs rc = %d", rc));
+ cFYI(1, "SetFSize for attrs rc = %d", rc);
if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
unsigned int bytes_written;
rc = CIFSSMBWrite(xid, pTcon, nfid, 0, attrs->ia_size,
&bytes_written, NULL, NULL, 1);
- cFYI(1, ("Wrt seteof rc %d", rc));
+ cFYI(1, "Wrt seteof rc %d", rc);
}
} else
rc = -EINVAL;
@@ -1709,7 +1726,7 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
false, cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
- cFYI(1, ("SetEOF by path (setattrs) rc = %d", rc));
+ cFYI(1, "SetEOF by path (setattrs) rc = %d", rc);
if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
__u16 netfid;
int oplock = 0;
@@ -1726,7 +1743,7 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
attrs->ia_size,
&bytes_written, NULL,
NULL, 1);
- cFYI(1, ("wrt seteof rc %d", rc));
+ cFYI(1, "wrt seteof rc %d", rc);
CIFSSMBClose(xid, pTcon, netfid);
}
}
@@ -1754,8 +1771,8 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
struct cifs_unix_set_info_args *args = NULL;
struct cifsFileInfo *open_file;
- cFYI(1, ("setattr_unix on file %s attrs->ia_valid=0x%x",
- direntry->d_name.name, attrs->ia_valid));
+ cFYI(1, "setattr_unix on file %s attrs->ia_valid=0x%x",
+ direntry->d_name.name, attrs->ia_valid);
xid = GetXid();
@@ -1885,8 +1902,8 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
xid = GetXid();
- cFYI(1, ("setattr on file %s attrs->iavalid 0x%x",
- direntry->d_name.name, attrs->ia_valid));
+ cFYI(1, "setattr on file %s attrs->iavalid 0x%x",
+ direntry->d_name.name, attrs->ia_valid);
if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) == 0) {
/* check if we have permission to change attrs */
@@ -1943,7 +1960,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
attrs->ia_valid &= ~ATTR_MODE;
if (attrs->ia_valid & ATTR_MODE) {
- cFYI(1, ("Mode changed to 0%o", attrs->ia_mode));
+ cFYI(1, "Mode changed to 0%o", attrs->ia_mode);
mode = attrs->ia_mode;
}
@@ -2029,7 +2046,7 @@ cifs_setattr(struct dentry *direntry, struct iattr *attrs)
#if 0
void cifs_delete_inode(struct inode *inode)
{
- cFYI(1, ("In cifs_delete_inode, inode = 0x%p", inode));
+ cFYI(1, "In cifs_delete_inode, inode = 0x%p", inode);
/* may have to add back in if and when safe distributed caching of
directories added e.g. via FindNotify */
}