Merge tag 'iwlwifi-for-kalle-2015-05-28' of https://git.kernel.org/pub/scm/linux...
[cascardo/linux.git] / fs / nfs / nfs4proc.c
index 627f37c..45b35b9 100644 (file)
@@ -51,7 +51,6 @@
 #include <linux/namei.h>
 #include <linux/mount.h>
 #include <linux/module.h>
-#include <linux/nfs_idmap.h>
 #include <linux/xattr.h>
 #include <linux/utsname.h>
 #include <linux/freezer.h>
@@ -63,6 +62,7 @@
 #include "callback.h"
 #include "pnfs.h"
 #include "netns.h"
+#include "nfs4idmap.h"
 #include "nfs4session.h"
 #include "fscache.h"
 
@@ -185,7 +185,8 @@ const u32 nfs4_fattr_bitmap[3] = {
        | FATTR4_WORD1_SPACE_USED
        | FATTR4_WORD1_TIME_ACCESS
        | FATTR4_WORD1_TIME_METADATA
-       | FATTR4_WORD1_TIME_MODIFY,
+       | FATTR4_WORD1_TIME_MODIFY
+       | FATTR4_WORD1_MOUNTED_ON_FILEID,
 #ifdef CONFIG_NFS_V4_SECURITY_LABEL
        FATTR4_WORD2_SECURITY_LABEL
 #endif
@@ -293,7 +294,7 @@ static void nfs4_setup_readdir(u64 cookie, __be32 *verifier, struct dentry *dent
                *p++ = xdr_one;                         /* bitmap length */
                *p++ = htonl(FATTR4_WORD0_FILEID);             /* bitmap */
                *p++ = htonl(8);              /* attribute buffer length */
-               p = xdr_encode_hyper(p, NFS_FILEID(dentry->d_inode));
+               p = xdr_encode_hyper(p, NFS_FILEID(d_inode(dentry)));
        }
        
        *p++ = xdr_one;                                  /* next */
@@ -305,7 +306,7 @@ static void nfs4_setup_readdir(u64 cookie, __be32 *verifier, struct dentry *dent
        *p++ = xdr_one;                         /* bitmap length */
        *p++ = htonl(FATTR4_WORD0_FILEID);             /* bitmap */
        *p++ = htonl(8);              /* attribute buffer length */
-       p = xdr_encode_hyper(p, NFS_FILEID(dentry->d_parent->d_inode));
+       p = xdr_encode_hyper(p, NFS_FILEID(d_inode(dentry->d_parent)));
 
        readdir->pgbase = (char *)p - (char *)start;
        readdir->count -= readdir->pgbase;
@@ -1004,7 +1005,7 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
                gfp_t gfp_mask)
 {
        struct dentry *parent = dget_parent(dentry);
-       struct inode *dir = parent->d_inode;
+       struct inode *dir = d_inode(parent);
        struct nfs_server *server = NFS_SERVER(dir);
        struct nfs_seqid *(*alloc_seqid)(struct nfs_seqid_counter *, gfp_t);
        struct nfs4_opendata *p;
@@ -1057,7 +1058,7 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
        case NFS4_OPEN_CLAIM_FH:
        case NFS4_OPEN_CLAIM_DELEG_CUR_FH:
        case NFS4_OPEN_CLAIM_DELEG_PREV_FH:
-               p->o_arg.fh = NFS_FH(dentry->d_inode);
+               p->o_arg.fh = NFS_FH(d_inode(dentry));
        }
        if (attrs != NULL && attrs->ia_valid != 0) {
                __u32 verf[2];
@@ -1794,7 +1795,7 @@ static const struct rpc_call_ops nfs4_open_confirm_ops = {
  */
 static int _nfs4_proc_open_confirm(struct nfs4_opendata *data)
 {
-       struct nfs_server *server = NFS_SERVER(data->dir->d_inode);
+       struct nfs_server *server = NFS_SERVER(d_inode(data->dir));
        struct rpc_task *task;
        struct  rpc_message msg = {
                .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_CONFIRM],
@@ -1951,7 +1952,7 @@ static const struct rpc_call_ops nfs4_open_ops = {
 
 static int nfs4_run_open_task(struct nfs4_opendata *data, int isrecover)
 {
-       struct inode *dir = data->dir->d_inode;
+       struct inode *dir = d_inode(data->dir);
        struct nfs_server *server = NFS_SERVER(dir);
        struct nfs_openargs *o_arg = &data->o_arg;
        struct nfs_openres *o_res = &data->o_res;
@@ -1998,7 +1999,7 @@ static int nfs4_run_open_task(struct nfs4_opendata *data, int isrecover)
 
 static int _nfs4_recover_proc_open(struct nfs4_opendata *data)
 {
-       struct inode *dir = data->dir->d_inode;
+       struct inode *dir = d_inode(data->dir);
        struct nfs_openres *o_res = &data->o_res;
         int status;
 
@@ -2067,7 +2068,7 @@ static int nfs4_opendata_access(struct rpc_cred *cred,
  */
 static int _nfs4_proc_open(struct nfs4_opendata *data)
 {
-       struct inode *dir = data->dir->d_inode;
+       struct inode *dir = d_inode(data->dir);
        struct nfs_server *server = NFS_SERVER(dir);
        struct nfs_openargs *o_arg = &data->o_arg;
        struct nfs_openres *o_res = &data->o_res;
@@ -2314,7 +2315,7 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata,
                set_bit(NFS_STATE_POSIX_LOCKS, &state->flags);
 
        dentry = opendata->dentry;
-       if (dentry->d_inode == NULL) {
+       if (d_really_is_negative(dentry)) {
                /* FIXME: Is this d_drop() ever needed? */
                d_drop(dentry);
                dentry = d_add_unique(dentry, igrab(state->inode));
@@ -2325,7 +2326,7 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata,
                        ctx->dentry = dget(dentry);
                }
                nfs_set_verifier(dentry,
-                               nfs_save_change_attribute(opendata->dir->d_inode));
+                               nfs_save_change_attribute(d_inode(opendata->dir)));
        }
 
        ret = nfs4_opendata_access(sp->so_cred, opendata, state, fmode, flags);
@@ -2333,7 +2334,7 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata,
                goto out;
 
        ctx->state = state;
-       if (dentry->d_inode == state->inode) {
+       if (d_inode(dentry) == state->inode) {
                nfs_inode_attach_open_context(ctx);
                if (read_seqcount_retry(&sp->so_reclaim_seqcount, seq))
                        nfs4_schedule_stateid_recovery(server, state);
@@ -2374,10 +2375,10 @@ static int _nfs4_do_open(struct inode *dir,
        status = nfs4_recover_expired_lease(server);
        if (status != 0)
                goto err_put_state_owner;
-       if (dentry->d_inode != NULL)
-               nfs4_return_incompatible_delegation(dentry->d_inode, fmode);
+       if (d_really_is_positive(dentry))
+               nfs4_return_incompatible_delegation(d_inode(dentry), fmode);
        status = -ENOMEM;
-       if (dentry->d_inode)
+       if (d_really_is_positive(dentry))
                claim = NFS4_OPEN_CLAIM_FH;
        opendata = nfs4_opendata_alloc(dentry, sp, fmode, flags, sattr,
                        label, claim, GFP_KERNEL);
@@ -2400,8 +2401,8 @@ static int _nfs4_do_open(struct inode *dir,
                }
                opendata->o_arg.open_bitmap = &nfs4_pnfs_open_bitmap[0];
        }
-       if (dentry->d_inode != NULL)
-               opendata->state = nfs4_get_open_state(dentry->d_inode, sp);
+       if (d_really_is_positive(dentry))
+               opendata->state = nfs4_get_open_state(d_inode(dentry), sp);
 
        status = _nfs4_open_and_get_state(opendata, fmode, flags, ctx);
        if (status != 0)
@@ -3095,16 +3096,13 @@ int nfs4_proc_get_rootfh(struct nfs_server *server, struct nfs_fh *fhandle,
                         struct nfs_fsinfo *info,
                         bool auth_probe)
 {
-       int status;
+       int status = 0;
 
-       switch (auth_probe) {
-       case false:
+       if (!auth_probe)
                status = nfs4_lookup_root(server, fhandle, info);
-               if (status != -NFS4ERR_WRONGSEC)
-                       break;
-       default:
+
+       if (auth_probe || status == NFS4ERR_WRONGSEC)
                status = nfs4_do_find_root_sec(server, fhandle, info);
-       }
 
        if (status == 0)
                status = nfs4_server_capabilities(server, fhandle);
@@ -3254,7 +3252,7 @@ static int
 nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
                  struct iattr *sattr)
 {
-       struct inode *inode = dentry->d_inode;
+       struct inode *inode = d_inode(dentry);
        struct rpc_cred *cred = NULL;
        struct nfs4_state *state = NULL;
        struct nfs4_label *label = NULL;
@@ -3871,13 +3869,13 @@ static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
 static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
                u64 cookie, struct page **pages, unsigned int count, int plus)
 {
-       struct inode            *dir = dentry->d_inode;
+       struct inode            *dir = d_inode(dentry);
        struct nfs4_readdir_arg args = {
                .fh = NFS_FH(dir),
                .pages = pages,
                .pgbase = 0,
                .count = count,
-               .bitmask = NFS_SERVER(dentry->d_inode)->attr_bitmask,
+               .bitmask = NFS_SERVER(d_inode(dentry))->attr_bitmask,
                .plus = plus,
        };
        struct nfs4_readdir_res res;
@@ -3914,8 +3912,8 @@ static int nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
        do {
                err = _nfs4_proc_readdir(dentry, cred, cookie,
                                pages, count, plus);
-               trace_nfs4_readdir(dentry->d_inode, err);
-               err = nfs4_handle_exception(NFS_SERVER(dentry->d_inode), err,
+               trace_nfs4_readdir(d_inode(dentry), err);
+               err = nfs4_handle_exception(NFS_SERVER(d_inode(dentry)), err,
                                &exception);
        } while (exception.retry);
        return err;
@@ -4830,7 +4828,7 @@ nfs4_set_security_label(struct dentry *dentry, const void *buf, size_t buflen)
        struct nfs4_label ilabel, *olabel = NULL;
        struct nfs_fattr fattr;
        struct rpc_cred *cred;
-       struct inode *inode = dentry->d_inode;
+       struct inode *inode = d_inode(dentry);
        int status;
 
        if (!nfs_server_capable(inode, NFS_CAP_SECURITY_LABEL))
@@ -5670,7 +5668,7 @@ static void nfs4_lock_done(struct rpc_task *task, void *calldata)
        data->rpc_status = task->tk_status;
        switch (task->tk_status) {
        case 0:
-               renew_lease(NFS_SERVER(data->ctx->dentry->d_inode),
+               renew_lease(NFS_SERVER(d_inode(data->ctx->dentry)),
                                data->timestamp);
                if (data->arg.new_lock) {
                        data->fl.fl_flags &= ~(FL_SLEEP | FL_ACCESS);
@@ -6112,7 +6110,7 @@ static int nfs4_xattr_set_nfs4_acl(struct dentry *dentry, const char *key,
        if (strcmp(key, "") != 0)
                return -EINVAL;
 
-       return nfs4_proc_set_acl(dentry->d_inode, buf, buflen);
+       return nfs4_proc_set_acl(d_inode(dentry), buf, buflen);
 }
 
 static int nfs4_xattr_get_nfs4_acl(struct dentry *dentry, const char *key,
@@ -6121,7 +6119,7 @@ static int nfs4_xattr_get_nfs4_acl(struct dentry *dentry, const char *key,
        if (strcmp(key, "") != 0)
                return -EINVAL;
 
-       return nfs4_proc_get_acl(dentry->d_inode, buf, buflen);
+       return nfs4_proc_get_acl(d_inode(dentry), buf, buflen);
 }
 
 static size_t nfs4_xattr_list_nfs4_acl(struct dentry *dentry, char *list,
@@ -6130,7 +6128,7 @@ static size_t nfs4_xattr_list_nfs4_acl(struct dentry *dentry, char *list,
 {
        size_t len = sizeof(XATTR_NAME_NFSV4_ACL);
 
-       if (!nfs4_server_supports_acls(NFS_SERVER(dentry->d_inode)))
+       if (!nfs4_server_supports_acls(NFS_SERVER(d_inode(dentry))))
                return 0;
 
        if (list && len <= list_len)
@@ -6158,7 +6156,7 @@ static int nfs4_xattr_get_nfs4_label(struct dentry *dentry, const char *key,
                                   void *buf, size_t buflen, int type)
 {
        if (security_ismaclabel(key))
-               return nfs4_get_security_label(dentry->d_inode, buf, buflen);
+               return nfs4_get_security_label(d_inode(dentry), buf, buflen);
        return -EOPNOTSUPP;
 }
 
@@ -6168,10 +6166,10 @@ static size_t nfs4_xattr_list_nfs4_label(struct dentry *dentry, char *list,
 {
        size_t len = 0;
 
-       if (nfs_server_capable(dentry->d_inode, NFS_CAP_SECURITY_LABEL)) {
-               len = security_inode_listsecurity(dentry->d_inode, NULL, 0);
+       if (nfs_server_capable(d_inode(dentry), NFS_CAP_SECURITY_LABEL)) {
+               len = security_inode_listsecurity(d_inode(dentry), NULL, 0);
                if (list && len <= list_len)
-                       security_inode_listsecurity(dentry->d_inode, list, len);
+                       security_inode_listsecurity(d_inode(dentry), list, len);
        }
        return len;
 }
@@ -7944,6 +7942,8 @@ _nfs4_proc_getdeviceinfo(struct nfs_server *server,
 {
        struct nfs4_getdeviceinfo_args args = {
                .pdev = pdev,
+               .notify_types = NOTIFY_DEVICEID4_CHANGE |
+                       NOTIFY_DEVICEID4_DELETE,
        };
        struct nfs4_getdeviceinfo_res res = {
                .pdev = pdev,
@@ -7958,6 +7958,11 @@ _nfs4_proc_getdeviceinfo(struct nfs_server *server,
 
        dprintk("--> %s\n", __func__);
        status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0);
+       if (res.notification & ~args.notify_types)
+               dprintk("%s: unsupported notification\n", __func__);
+       if (res.notification != args.notify_types)
+               pdev->nocache = 1;
+
        dprintk("<-- %s status=%d\n", __func__, status);
 
        return status;