~ubuntu-branches/ubuntu/trusty/linux-armadaxp/trusty

« back to all changes in this revision

Viewing changes to fs/ceph/mds_client.c

  • Committer: Package Import Robot
  • Author(s): Michael Casadevall, Bryan Wu, Dann Frazier, Michael Casadeall
  • Date: 2012-03-10 15:00:54 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20120310150054-flugb39zon8vvgwe
Tags: 3.2.0-1600.1
[ Bryan Wu ]
* UBUNTU: import debian/debian.env and debian.armadaxp

[ Dann Frazier ]
* ARM: Armada XP: remove trailing '/' in dirnames in mvRules.mk

[ Michael Casadeall ]
* tools: add some tools for Marvell Armada XP processor
* kernel: timer tick hacking from Marvell
* kernel: Sheeva Errata: add delay on Sheeva when powering down
* net: add Marvell NFP netfilter
* net: socket and skb modifications made by Marvell
* miscdevice: add minor IDs for some Marvell Armada drivers
* fs: introduce memory pool for splice()
* video: EDID detection updates from Marvell Armada XP patchset
* video: backlight: add Marvell Dove LCD backlight driver
* video: display: add THS8200 display driver
* video: framebuffer: add Marvell Dove and Armada XP processor onchip LCD controller driver
* usbtest: add Interrupt transfer testing by Marvell Armada XP code
* usb: ehci: add support for Marvell EHCI controler
* tty/serial: 8250: add support for Marvell Armada XP processor and DeviceTree work
* rtc: add support for Marvell Armada XP onchip RTC controller
* net: pppoe: add Marvell ethernet NFP hook in PPPoE networking driver
* mtd: nand: add support for Marvell Armada XP Nand Flash Controller
* mtd: maps: add Marvell Armada XP specific map driver
* mmc: add support for Marvell Armada XP MMC/SD host controller
* i2c: add support for Marvell Armada XP onchip i2c bus controller
* hwmon: add Kconfig option for Armada XP onchip thermal sensor driver
* dmaengine: add Net DMA support for splice and update Marvell XOR DMA engine driver
* ata: add support for Marvell Armada XP SATA controller and update some quirks
* ARM: add Marvell Armada XP machine to mach-types
* ARM: oprofile: add support for Marvell PJ4B core
* ARM: mm: more ARMv6 switches for Marvell Armada XP
* ARM: remove static declaration to allow compilation
* ARM: alignment access fault trick
* ARM: mm: skip some fault fixing when run on NONE SMP ARMv6 mode during early abort event
* ARM: mm: add Marvell Sheeva CPU Architecture for PJ4B
* ARM: introduce optimized copy operation for Marvell Armada XP
* ARM: SAUCE: hardware breakpoint trick for Marvell Armada XP
* ARM: big endian and little endian tricks for Marvell Armada XP
* ARM: SAUCE: Add Marvell Armada XP build rules to arch/arm/kernel/Makefile
* ARM: vfp: add special handling for Marvell Armada XP
* ARM: add support for Marvell U-Boot
* ARM: add mv_controller_num for ARM PCI drivers
* ARM: add support for local PMUs, general SMP tweaks and cache flushing
* ARM: add Marvell device identifies in glue-proc.h
* ARM: add IPC driver support for Marvell platforms
* ARM: add DMA mapping for Marvell platforms
* ARM: add Sheeva errata and PJ4B code for booting
* ARM: update Kconfig and Makefile to include Marvell Armada XP platforms
* ARM: Armada XP: import LSP from Marvell for Armada XP 3.2 kernel enablement

Show diffs side-by-side

added added

removed removed

Lines of Context:
483
483
                destroy_reply_info(&req->r_reply_info);
484
484
        }
485
485
        if (req->r_inode) {
486
 
                ceph_put_cap_refs(ceph_inode(req->r_inode),
487
 
                                  CEPH_CAP_PIN);
 
486
                ceph_put_cap_refs(ceph_inode(req->r_inode), CEPH_CAP_PIN);
488
487
                iput(req->r_inode);
489
488
        }
490
489
        if (req->r_locked_dir)
491
 
                ceph_put_cap_refs(ceph_inode(req->r_locked_dir),
492
 
                                  CEPH_CAP_PIN);
 
490
                ceph_put_cap_refs(ceph_inode(req->r_locked_dir), CEPH_CAP_PIN);
493
491
        if (req->r_target_inode)
494
492
                iput(req->r_target_inode);
495
493
        if (req->r_dentry)
496
494
                dput(req->r_dentry);
497
495
        if (req->r_old_dentry) {
498
 
                ceph_put_cap_refs(
499
 
                        ceph_inode(req->r_old_dentry->d_parent->d_inode),
500
 
                        CEPH_CAP_PIN);
 
496
                /*
 
497
                 * track (and drop pins for) r_old_dentry_dir
 
498
                 * separately, since r_old_dentry's d_parent may have
 
499
                 * changed between the dir mutex being dropped and
 
500
                 * this request being freed.
 
501
                 */
 
502
                ceph_put_cap_refs(ceph_inode(req->r_old_dentry_dir),
 
503
                                  CEPH_CAP_PIN);
501
504
                dput(req->r_old_dentry);
 
505
                iput(req->r_old_dentry_dir);
502
506
        }
503
507
        kfree(req->r_path1);
504
508
        kfree(req->r_path2);
615
619
 *
616
620
 * Called under mdsc->mutex.
617
621
 */
618
 
struct dentry *get_nonsnap_parent(struct dentry *dentry)
 
622
static struct dentry *get_nonsnap_parent(struct dentry *dentry)
619
623
{
 
624
        /*
 
625
         * we don't need to worry about protecting the d_parent access
 
626
         * here because we never renaming inside the snapped namespace
 
627
         * except to resplice to another snapdir, and either the old or new
 
628
         * result is a valid result.
 
629
         */
620
630
        while (!IS_ROOT(dentry) && ceph_snap(dentry->d_inode) != CEPH_NOSNAP)
621
631
                dentry = dentry->d_parent;
622
632
        return dentry;
652
662
        if (req->r_inode) {
653
663
                inode = req->r_inode;
654
664
        } else if (req->r_dentry) {
655
 
                struct inode *dir = req->r_dentry->d_parent->d_inode;
 
665
                /* ignore race with rename; old or new d_parent is okay */
 
666
                struct dentry *parent = req->r_dentry->d_parent;
 
667
                struct inode *dir = parent->d_inode;
656
668
 
657
669
                if (dir->i_sb != mdsc->fsc->sb) {
658
670
                        /* not this fs! */
660
672
                } else if (ceph_snap(dir) != CEPH_NOSNAP) {
661
673
                        /* direct snapped/virtual snapdir requests
662
674
                         * based on parent dir inode */
663
 
                        struct dentry *dn =
664
 
                                get_nonsnap_parent(req->r_dentry->d_parent);
 
675
                        struct dentry *dn = get_nonsnap_parent(parent);
665
676
                        inode = dn->d_inode;
666
677
                        dout("__choose_mds using nonsnap parent %p\n", inode);
667
678
                } else if (req->r_dentry->d_inode) {
670
681
                } else {
671
682
                        /* dir + name */
672
683
                        inode = dir;
673
 
                        hash = ceph_dentry_hash(req->r_dentry);
 
684
                        hash = ceph_dentry_hash(dir, req->r_dentry);
674
685
                        is_hash = true;
675
686
                }
676
687
        }
721
732
                }
722
733
        }
723
734
 
724
 
        spin_lock(&inode->i_lock);
 
735
        spin_lock(&ci->i_ceph_lock);
725
736
        cap = NULL;
726
737
        if (mode == USE_AUTH_MDS)
727
738
                cap = ci->i_auth_cap;
728
739
        if (!cap && !RB_EMPTY_ROOT(&ci->i_caps))
729
740
                cap = rb_entry(rb_first(&ci->i_caps), struct ceph_cap, ci_node);
730
741
        if (!cap) {
731
 
                spin_unlock(&inode->i_lock);
 
742
                spin_unlock(&ci->i_ceph_lock);
732
743
                goto random;
733
744
        }
734
745
        mds = cap->session->s_mds;
735
746
        dout("choose_mds %p %llx.%llx mds%d (%scap %p)\n",
736
747
             inode, ceph_vinop(inode), mds,
737
748
             cap == ci->i_auth_cap ? "auth " : "", cap);
738
 
        spin_unlock(&inode->i_lock);
 
749
        spin_unlock(&ci->i_ceph_lock);
739
750
        return mds;
740
751
 
741
752
random:
753
764
        struct ceph_msg *msg;
754
765
        struct ceph_mds_session_head *h;
755
766
 
756
 
        msg = ceph_msg_new(CEPH_MSG_CLIENT_SESSION, sizeof(*h), GFP_NOFS);
 
767
        msg = ceph_msg_new(CEPH_MSG_CLIENT_SESSION, sizeof(*h), GFP_NOFS,
 
768
                           false);
757
769
        if (!msg) {
758
770
                pr_err("create_session_msg ENOMEM creating msg\n");
759
771
                return NULL;
939
951
 
940
952
        dout("removing cap %p, ci is %p, inode is %p\n",
941
953
             cap, ci, &ci->vfs_inode);
942
 
        spin_lock(&inode->i_lock);
 
954
        spin_lock(&ci->i_ceph_lock);
943
955
        __ceph_remove_cap(cap);
944
956
        if (!__ceph_is_any_real_caps(ci)) {
945
957
                struct ceph_mds_client *mdsc =
972
984
                }
973
985
                spin_unlock(&mdsc->cap_dirty_lock);
974
986
        }
975
 
        spin_unlock(&inode->i_lock);
 
987
        spin_unlock(&ci->i_ceph_lock);
976
988
        while (drop--)
977
989
                iput(inode);
978
990
        return 0;
1003
1015
 
1004
1016
        wake_up_all(&ci->i_cap_wq);
1005
1017
        if (arg) {
1006
 
                spin_lock(&inode->i_lock);
 
1018
                spin_lock(&ci->i_ceph_lock);
1007
1019
                ci->i_wanted_max_size = 0;
1008
1020
                ci->i_requested_max_size = 0;
1009
 
                spin_unlock(&inode->i_lock);
 
1021
                spin_unlock(&ci->i_ceph_lock);
1010
1022
        }
1011
1023
        return 0;
1012
1024
}
1139
1151
        if (session->s_trim_caps <= 0)
1140
1152
                return -1;
1141
1153
 
1142
 
        spin_lock(&inode->i_lock);
 
1154
        spin_lock(&ci->i_ceph_lock);
1143
1155
        mine = cap->issued | cap->implemented;
1144
1156
        used = __ceph_caps_used(ci);
1145
1157
        oissued = __ceph_caps_issued_other(ci, cap);
1158
1170
                __ceph_remove_cap(cap);
1159
1171
        } else {
1160
1172
                /* try to drop referring dentries */
1161
 
                spin_unlock(&inode->i_lock);
 
1173
                spin_unlock(&ci->i_ceph_lock);
1162
1174
                d_prune_aliases(inode);
1163
1175
                dout("trim_caps_cb %p cap %p  pruned, count now %d\n",
1164
1176
                     inode, cap, atomic_read(&inode->i_count));
1166
1178
        }
1167
1179
 
1168
1180
out:
1169
 
        spin_unlock(&inode->i_lock);
 
1181
        spin_unlock(&ci->i_ceph_lock);
1170
1182
        return 0;
1171
1183
}
1172
1184
 
1229
1241
        while (session->s_num_cap_releases < session->s_nr_caps + extra) {
1230
1242
                spin_unlock(&session->s_cap_lock);
1231
1243
                msg = ceph_msg_new(CEPH_MSG_CLIENT_CAPRELEASE, PAGE_CACHE_SIZE,
1232
 
                                   GFP_NOFS);
 
1244
                                   GFP_NOFS, false);
1233
1245
                if (!msg)
1234
1246
                        goto out_unlocked;
1235
1247
                dout("add_cap_releases %p msg %p now %d\n", session, msg,
1284
1296
                                           i_flushing_item);
1285
1297
                        struct inode *inode = &ci->vfs_inode;
1286
1298
 
1287
 
                        spin_lock(&inode->i_lock);
 
1299
                        spin_lock(&ci->i_ceph_lock);
1288
1300
                        if (ci->i_cap_flush_seq <= want_flush_seq) {
1289
1301
                                dout("check_cap_flush still flushing %p "
1290
1302
                                     "seq %lld <= %lld to mds%d\n", inode,
1292
1304
                                     session->s_mds);
1293
1305
                                ret = 0;
1294
1306
                        }
1295
 
                        spin_unlock(&inode->i_lock);
 
1307
                        spin_unlock(&ci->i_ceph_lock);
1296
1308
                }
1297
1309
                mutex_unlock(&session->s_mutex);
1298
1310
                ceph_put_mds_session(session);
1483
1495
                             pos, temp);
1484
1496
                } else if (stop_on_nosnap && inode &&
1485
1497
                           ceph_snap(inode) == CEPH_NOSNAP) {
 
1498
                        spin_unlock(&temp->d_lock);
1486
1499
                        break;
1487
1500
                } else {
1488
1501
                        pos -= temp->d_name.len;
1584
1597
                r = build_dentry_path(rdentry, ppath, pathlen, ino, freepath);
1585
1598
                dout(" dentry %p %llx/%.*s\n", rdentry, *ino, *pathlen,
1586
1599
                     *ppath);
1587
 
        } else if (rpath) {
 
1600
        } else if (rpath || rino) {
1588
1601
                *ino = rino;
1589
1602
                *ppath = rpath;
1590
1603
                *pathlen = strlen(rpath);
1641
1654
        if (req->r_old_dentry_drop)
1642
1655
                len += req->r_old_dentry->d_name.len;
1643
1656
 
1644
 
        msg = ceph_msg_new(CEPH_MSG_CLIENT_REQUEST, len, GFP_NOFS);
 
1657
        msg = ceph_msg_new(CEPH_MSG_CLIENT_REQUEST, len, GFP_NOFS, false);
1645
1658
        if (!msg) {
1646
1659
                msg = ERR_PTR(-ENOMEM);
1647
1660
                goto out_free2;
1931
1944
        if (req->r_locked_dir)
1932
1945
                ceph_get_cap_refs(ceph_inode(req->r_locked_dir), CEPH_CAP_PIN);
1933
1946
        if (req->r_old_dentry)
1934
 
                ceph_get_cap_refs(
1935
 
                        ceph_inode(req->r_old_dentry->d_parent->d_inode),
1936
 
                        CEPH_CAP_PIN);
 
1947
                ceph_get_cap_refs(ceph_inode(req->r_old_dentry_dir),
 
1948
                                  CEPH_CAP_PIN);
1937
1949
 
1938
1950
        /* issue */
1939
1951
        mutex_lock(&mdsc->mutex);
1991
2003
}
1992
2004
 
1993
2005
/*
1994
 
 * Invalidate dir I_COMPLETE, dentry lease state on an aborted MDS
 
2006
 * Invalidate dir D_COMPLETE, dentry lease state on an aborted MDS
1995
2007
 * namespace request.
1996
2008
 */
1997
2009
void ceph_invalidate_dir_request(struct ceph_mds_request *req)
1999
2011
        struct inode *inode = req->r_locked_dir;
2000
2012
        struct ceph_inode_info *ci = ceph_inode(inode);
2001
2013
 
2002
 
        dout("invalidate_dir_request %p (I_COMPLETE, lease(s))\n", inode);
2003
 
        spin_lock(&inode->i_lock);
2004
 
        ci->i_ceph_flags &= ~CEPH_I_COMPLETE;
 
2014
        dout("invalidate_dir_request %p (D_COMPLETE, lease(s))\n", inode);
 
2015
        spin_lock(&ci->i_ceph_lock);
 
2016
        ceph_dir_clear_complete(inode);
2005
2017
        ci->i_release_count++;
2006
 
        spin_unlock(&inode->i_lock);
 
2018
        spin_unlock(&ci->i_ceph_lock);
2007
2019
 
2008
2020
        if (req->r_dentry)
2009
2021
                ceph_invalidate_dentry_lease(req->r_dentry);
2411
2423
        if (err)
2412
2424
                goto out_free;
2413
2425
 
2414
 
        spin_lock(&inode->i_lock);
 
2426
        spin_lock(&ci->i_ceph_lock);
2415
2427
        cap->seq = 0;        /* reset cap seq */
2416
2428
        cap->issue_seq = 0;  /* and issue_seq */
2417
2429
 
2434
2446
                rec.v1.pathbase = cpu_to_le64(pathbase);
2435
2447
                reclen = sizeof(rec.v1);
2436
2448
        }
2437
 
        spin_unlock(&inode->i_lock);
 
2449
        spin_unlock(&ci->i_ceph_lock);
2438
2450
 
2439
2451
        if (recon_state->flock) {
2440
2452
                int num_fcntl_locks, num_flock_locks;
2508
2520
                goto fail_nopagelist;
2509
2521
        ceph_pagelist_init(pagelist);
2510
2522
 
2511
 
        reply = ceph_msg_new(CEPH_MSG_CLIENT_RECONNECT, 0, GFP_NOFS);
 
2523
        reply = ceph_msg_new(CEPH_MSG_CLIENT_RECONNECT, 0, GFP_NOFS, false);
2512
2524
        if (!reply)
2513
2525
                goto fail_nomsg;
2514
2526
 
2714
2726
        struct ceph_mds_lease *h = msg->front.iov_base;
2715
2727
        u32 seq;
2716
2728
        struct ceph_vino vino;
2717
 
        int mask;
2718
2729
        struct qstr dname;
2719
2730
        int release = 0;
2720
2731
 
2725
2736
                goto bad;
2726
2737
        vino.ino = le64_to_cpu(h->ino);
2727
2738
        vino.snap = CEPH_NOSNAP;
2728
 
        mask = le16_to_cpu(h->mask);
2729
2739
        seq = le32_to_cpu(h->seq);
2730
2740
        dname.name = (void *)h + sizeof(*h) + sizeof(u32);
2731
2741
        dname.len = msg->front.iov_len - sizeof(*h) - sizeof(u32);
2737
2747
 
2738
2748
        /* lookup inode */
2739
2749
        inode = ceph_find_inode(sb, vino);
2740
 
        dout("handle_lease %s, mask %d, ino %llx %p %.*s\n",
2741
 
             ceph_lease_op_name(h->action), mask, vino.ino, inode,
 
2750
        dout("handle_lease %s, ino %llx %p %.*s\n",
 
2751
             ceph_lease_op_name(h->action), vino.ino, inode,
2742
2752
             dname.len, dname.name);
2743
2753
        if (inode == NULL) {
2744
2754
                dout("handle_lease no inode %llx\n", vino.ino);
2823
2833
        dnamelen = dentry->d_name.len;
2824
2834
        len += dnamelen;
2825
2835
 
2826
 
        msg = ceph_msg_new(CEPH_MSG_CLIENT_LEASE, len, GFP_NOFS);
 
2836
        msg = ceph_msg_new(CEPH_MSG_CLIENT_LEASE, len, GFP_NOFS, false);
2827
2837
        if (!msg)
2828
2838
                return;
2829
2839
        lease = msg->front.iov_base;
2830
2840
        lease->action = action;
2831
 
        lease->mask = cpu_to_le16(1);
2832
2841
        lease->ino = cpu_to_le64(ceph_vino(inode).ino);
2833
2842
        lease->first = lease->last = cpu_to_le64(ceph_vino(inode).snap);
2834
2843
        lease->seq = cpu_to_le32(seq);
2850
2859
 * Pass @inode always, @dentry is optional.
2851
2860
 */
2852
2861
void ceph_mdsc_lease_release(struct ceph_mds_client *mdsc, struct inode *inode,
2853
 
                             struct dentry *dentry, int mask)
 
2862
                             struct dentry *dentry)
2854
2863
{
2855
2864
        struct ceph_dentry_info *di;
2856
2865
        struct ceph_mds_session *session;
2858
2867
 
2859
2868
        BUG_ON(inode == NULL);
2860
2869
        BUG_ON(dentry == NULL);
2861
 
        BUG_ON(mask == 0);
2862
2870
 
2863
2871
        /* is dentry lease valid? */
2864
2872
        spin_lock(&dentry->d_lock);
2868
2876
            di->lease_gen != di->lease_session->s_cap_gen ||
2869
2877
            !time_before(jiffies, dentry->d_time)) {
2870
2878
                dout("lease_release inode %p dentry %p -- "
2871
 
                     "no lease on %d\n",
2872
 
                     inode, dentry, mask);
 
2879
                     "no lease\n",
 
2880
                     inode, dentry);
2873
2881
                spin_unlock(&dentry->d_lock);
2874
2882
                return;
2875
2883
        }
2880
2888
        __ceph_mdsc_drop_dentry_lease(dentry);
2881
2889
        spin_unlock(&dentry->d_lock);
2882
2890
 
2883
 
        dout("lease_release inode %p dentry %p mask %d to mds%d\n",
2884
 
             inode, dentry, mask, session->s_mds);
 
2891
        dout("lease_release inode %p dentry %p to mds%d\n",
 
2892
             inode, dentry, session->s_mds);
2885
2893
        ceph_mdsc_lease_send_msg(session, inode, dentry,
2886
2894
                                 CEPH_MDS_LEASE_RELEASE, seq);
2887
2895
        ceph_put_mds_session(session);
3147
3155
/*
3148
3156
 * true if all sessions are closed, or we force unmount
3149
3157
 */
3150
 
bool done_closing_sessions(struct ceph_mds_client *mdsc)
 
3158
static bool done_closing_sessions(struct ceph_mds_client *mdsc)
3151
3159
{
3152
3160
        int i, n = 0;
3153
3161